diff options
author | max42 <max42@yandex-team.com> | 2023-06-30 11:13:34 +0300 |
---|---|---|
committer | max42 <max42@yandex-team.com> | 2023-06-30 11:13:34 +0300 |
commit | 3e1899838408bbad47622007aa382bc8a2b01f87 (patch) | |
tree | 0f21c1e6add187ddb6c3ccc048a7d640ce03fb87 /contrib/libs/flatbuffers | |
parent | 5463eb3f5e72a86f858a3d27c886470a724ede34 (diff) | |
download | ydb-3e1899838408bbad47622007aa382bc8a2b01f87.tar.gz |
Revert "YT-19324: move YT provider to ydb/library/yql"
This reverts commit ca272f12fdd0e8d5c3e957fc87939148f1caaf72, reversing
changes made to 49f8acfc8b0b5c0071b804423bcf53fda26c7c12.
Diffstat (limited to 'contrib/libs/flatbuffers')
55 files changed, 0 insertions, 40834 deletions
diff --git a/contrib/libs/flatbuffers/CONTRIBUTING.md b/contrib/libs/flatbuffers/CONTRIBUTING.md deleted file mode 100644 index 17428add54..0000000000 --- a/contrib/libs/flatbuffers/CONTRIBUTING.md +++ /dev/null @@ -1,42 +0,0 @@ -Contributing {#contributing} -============ - -Want to contribute? Great! First, read this page (including the small print at -the end). - -# Before you contribute -Before we can use your code, you must sign the -[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1) -(CLA), which you can do online. The CLA is necessary mainly because you own the -copyright to your changes, even after your contribution becomes part of our -codebase, so we need your permission to use and distribute your code. We also -need to be sure of various other things—for instance that you'll tell us if you -know that your code infringes on other people's patents. You don't have to sign -the CLA until after you've submitted your code for review and a member has -approved it, but you must do it before we can put your code into our codebase. -Before you start working on a larger contribution, you should get in touch with -us first through the issue tracker with your idea so that we can help out and -possibly guide you. Coordinating up front makes it much easier to avoid -frustration later on. - -# Code reviews -All submissions, including submissions by project members, require review. We -use Github pull requests for this purpose. - -Some tips for good pull requests: -* Use our code - [style guide](https://google.github.io/styleguide/cppguide.html). - When in doubt, try to stay true to the existing code of the project. -* Write a descriptive commit message. What problem are you solving and what - are the consequences? Where and what did you test? Some good tips: - [here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message) - and [here](https://www.kernel.org/doc/Documentation/SubmittingPatches). -* If your PR consists of multiple commits which are successive improvements / - fixes to your first commit, consider squashing them into a single commit - (`git rebase -i`) such that your PR is a single commit on top of the current - HEAD. This make reviewing the code so much easier, and our history more - readable. - -# The small print -Contributions made by corporations are covered by a different agreement than -the one above, the Software Grant and Corporate Contributor License Agreement. diff --git a/contrib/libs/flatbuffers/LICENSE.txt b/contrib/libs/flatbuffers/LICENSE.txt deleted file mode 100644 index d645695673..0000000000 --- a/contrib/libs/flatbuffers/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/contrib/libs/flatbuffers/flatc/ya.make b/contrib/libs/flatbuffers/flatc/ya.make deleted file mode 100644 index 7186851a35..0000000000 --- a/contrib/libs/flatbuffers/flatc/ya.make +++ /dev/null @@ -1,56 +0,0 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -WITHOUT_LICENSE_TEXTS() - -LICENSE(Apache-2.0) - -ADDINCL( - contrib/libs/flatbuffers/grpc - contrib/libs/flatbuffers/include -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFLATBUFFERS_LOCALE_INDEPENDENT=1 -) - -SRCDIR(contrib/libs/flatbuffers) - -SRCS( - grpc/src/compiler/cpp_generator.cc - grpc/src/compiler/go_generator.cc - grpc/src/compiler/java_generator.cc - grpc/src/compiler/python_generator.cc - grpc/src/compiler/swift_generator.cc - grpc/src/compiler/ts_generator.cc - src/code_generators.cpp - src/flatc.cpp - src/idl_gen_cpp.cpp - src/idl_gen_cpp_yandex_maps_iter.cpp - src/idl_gen_csharp.cpp - src/idl_gen_dart.cpp - src/idl_gen_fbs.cpp - src/idl_gen_go.cpp - src/idl_gen_grpc.cpp - src/idl_gen_java.cpp - src/idl_gen_json_schema.cpp - src/idl_gen_kotlin.cpp - src/idl_gen_lobster.cpp - src/idl_gen_lua.cpp - src/idl_gen_php.cpp - src/idl_gen_python.cpp - src/idl_gen_rust.cpp - src/idl_gen_swift.cpp - src/idl_gen_text.cpp - src/idl_gen_ts.cpp - src/idl_parser.cpp - src/reflection.cpp - src/util.cpp -) - -END() diff --git a/contrib/libs/flatbuffers/grpc/README.md b/contrib/libs/flatbuffers/grpc/README.md deleted file mode 100644 index 685003f92b..0000000000 --- a/contrib/libs/flatbuffers/grpc/README.md +++ /dev/null @@ -1,43 +0,0 @@ -GRPC implementation and test -============================ - -NOTE: files in `src/` are shared with the GRPC project, and maintained there -(any changes should be submitted to GRPC instead). These files are copied -from GRPC, and work with both the Protobuf and FlatBuffers code generator. - -`tests/` contains a GRPC specific test, you need to have built and installed -the GRPC libraries for this to compile. This test will build using the -`FLATBUFFERS_BUILD_GRPCTEST` option to the main FlatBuffers CMake project. - -## Building Flatbuffers with gRPC - -### Linux - -1. Download, build and install gRPC. See [instructions](https://github.com/grpc/grpc/tree/master/src/cpp). - * Lets say your gRPC clone is at `/your/path/to/grpc_repo`. - * Install gRPC in a custom directory by running `make install prefix=/your/path/to/grpc_repo/install`. -2. `export GRPC_INSTALL_PATH=/your/path/to/grpc_repo/install` -3. `export PROTOBUF_DOWNLOAD_PATH=/your/path/to/grpc_repo/third_party/protobuf` -4. `mkdir build ; cd build` -5. `cmake -DFLATBUFFERS_BUILD_GRPCTEST=ON -DGRPC_INSTALL_PATH=${GRPC_INSTALL_PATH} -DPROTOBUF_DOWNLOAD_PATH=${PROTOBUF_DOWNLOAD_PATH} ..` -6. `make` - -For Bazel users: - -```shell -$bazel test src/compiler/... -``` - -## Running FlatBuffer gRPC tests - -### Linux - -1. `ln -s ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.6 ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.1` -2. `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${GRPC_INSTALL_PATH}/lib` -3. `make test ARGS=-V` - -For Bazel users: - -```shell -$bazel test tests/... -```
\ No newline at end of file diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/config.h b/contrib/libs/flatbuffers/grpc/src/compiler/config.h deleted file mode 100644 index 4adc594377..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/config.h +++ /dev/null @@ -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 diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/cpp_generator.cc b/contrib/libs/flatbuffers/grpc/src/compiler/cpp_generator.cc deleted file mode 100644 index 8dd408830c..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/cpp_generator.cc +++ /dev/null @@ -1,1780 +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. - * - */ - -#include <map> - -#include "src/compiler/cpp_generator.h" -#include "flatbuffers/util.h" - -#include <sstream> - -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) { - std::ostringstream out; - out << x; - return out.str(); -} - -inline bool ClientOnlyStreaming(const grpc_generator::Method *method) { - return method->ClientStreaming() && !method->ServerStreaming(); -} - -inline bool ServerOnlyStreaming(const grpc_generator::Method *method) { - return !method->ClientStreaming() && method->ServerStreaming(); -} - -grpc::string FilenameIdentifier(const grpc::string &filename) { - grpc::string result; - for (unsigned i = 0; i < filename.size(); i++) { - char c = filename[i]; - if (isalnum(c)) { - result.push_back(c); - } else { - static char hex[] = "0123456789abcdef"; - result.push_back('_'); - result.push_back(hex[(c >> 4) & 0xf]); - result.push_back(hex[c & 0xf]); - } - } - return result; -} -} // namespace - -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, - const Parameters ¶ms) { - std::map<grpc::string, grpc::string> vars; - - vars["l"] = params.use_system_headers ? '<' : '"'; - vars["r"] = params.use_system_headers ? '>' : '"'; - - auto &s = params.grpc_search_path; - if (!s.empty()) { - vars["l"] += s; - if (s[s.size() - 1] != '/') { - vars["l"] += '/'; - } - } - - for (auto i = headers.begin(); i != headers.end(); i++) { - vars["h"] = *i; - printer->Print(vars, "#include $l$$h$$r$\n"); - } -} - -grpc::string GetHeaderPrologue(grpc_generator::File *file, - const Parameters & /*params*/) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - std::map<grpc::string, grpc::string> vars; - - vars["filename"] = file->filename(); - vars["filename_identifier"] = FilenameIdentifier(file->filename()); - vars["filename_base"] = file->filename_without_ext(); - vars["message_header_ext"] = message_header_ext(); - - printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); - printer->Print(vars, - "// If you make any local change, they will be lost.\n"); - printer->Print(vars, "// source: $filename$\n"); - grpc::string leading_comments = file->GetLeadingComments("//"); - if (!leading_comments.empty()) { - printer->Print(vars, "// Original file comments:\n"); - printer->Print(leading_comments.c_str()); - } - printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n"); - printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n"); - printer->Print(vars, "\n"); - printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n"); - printer->Print(vars, file->additional_headers().c_str()); - printer->Print(vars, "\n"); - } - return output; -} - -grpc::string GetHeaderIncludes(grpc_generator::File *file, - const Parameters ¶ms) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - 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"}; - std::vector<grpc::string> headers(headers_strs, array_end(headers_strs)); - PrintIncludes(printer.get(), headers, params); - printer->Print(vars, "\n"); - printer->Print(vars, "namespace grpc {\n"); - printer->Print(vars, "class CompletionQueue;\n"); - printer->Print(vars, "class Channel;\n"); - printer->Print(vars, "class ServerCompletionQueue;\n"); - printer->Print(vars, "class ServerContext;\n"); - printer->Print(vars, "} // namespace grpc\n\n"); - - if (!file->package().empty()) { - std::vector<grpc::string> parts = file->package_parts(); - - for (auto part = parts.begin(); part != parts.end(); part++) { - vars["part"] = *part; - printer->Print(vars, "namespace $part$ {\n"); - } - printer->Print(vars, "\n"); - } - } - return output; -} - -void PrintHeaderClientMethodInterfaces( - grpc_generator::Printer *printer, const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars, bool is_public) { - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - - struct { - 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", "", ""}}; - - if (is_public) { - if (method->NoStreaming()) { - printer->Print( - *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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - printer->Print( - *vars, - "std::unique_ptr< " - "::grpc::ClientAsyncResponseReaderInterface< $Response$>> " - "$AsyncPrefix$$Method$(::grpc::ClientContext* context, " - "const $Request$& request, " - "::grpc::CompletionQueue* cq) {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< " - "::grpc::ClientAsyncResponseReaderInterface< $Response$>>(" - "$AsyncPrefix$$Method$Raw(context, request, cq));\n"); - printer->Outdent(); - printer->Print("}\n"); - } - } else if (ClientOnlyStreaming(method)) { - printer->Print( - *vars, - "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>" - " $Method$(" - "::grpc::ClientContext* context, $Response$* response) {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>" - "($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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncRawArgs"] = async_prefix.raw_args; - printer->Print( - *vars, - "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>" - " $AsyncPrefix$$Method$(::grpc::ClientContext* context, " - "$Response$* " - "response, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); - printer->Indent(); - printer->Print(*vars, - "return std::unique_ptr< " - "::grpc::ClientAsyncWriterInterface< $Request$>>(" - "$AsyncPrefix$$Method$Raw(context, response, " - "cq$AsyncRawArgs$));\n"); - printer->Outdent(); - printer->Print("}\n"); - } - } else if (ServerOnlyStreaming(method)) { - printer->Print( - *vars, - "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>" - " $Method$(::grpc::ClientContext* context, const $Request$& request)" - " {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>" - "($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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncRawArgs"] = async_prefix.raw_args; - printer->Print( - *vars, - "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> " - "$AsyncPrefix$$Method$(" - "::grpc::ClientContext* context, const $Request$& request, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< " - "::grpc::ClientAsyncReaderInterface< $Response$>>(" - "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n"); - printer->Outdent(); - printer->Print("}\n"); - } - } else if (method->BidiStreaming()) { - printer->Print(*vars, - "std::unique_ptr< ::grpc::ClientReaderWriterInterface< " - "$Request$, $Response$>> " - "$Method$(::grpc::ClientContext* context) {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< " - "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>(" - "$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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncRawArgs"] = async_prefix.raw_args; - printer->Print( - *vars, - "std::unique_ptr< " - "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> " - "$AsyncPrefix$$Method$(::grpc::ClientContext* context, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< " - "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>(" - "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n"); - printer->Outdent(); - printer->Print("}\n"); - } - } - } else { - if (method->NoStreaming()) { - 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, - "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* " - "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, " - "const $Request$& request, " - "::grpc::CompletionQueue* cq) = 0;\n"); - } - } else if (ClientOnlyStreaming(method)) { - printer->Print( - *vars, - "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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - printer->Print( - *vars, - "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*" - " $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, " - "$Response$* response, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n"); - } - } else if (ServerOnlyStreaming(method)) { - printer->Print( - *vars, - "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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - printer->Print( - *vars, - "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* " - "$AsyncPrefix$$Method$Raw(" - "::grpc::ClientContext* context, const $Request$& request, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n"); - } - } else if (method->BidiStreaming()) { - printer->Print(*vars, - "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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - printer->Print( - *vars, - "virtual ::grpc::ClientAsyncReaderWriterInterface< " - "$Request$, $Response$>* " - "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n"); - } - } - } -} - -void PrintHeaderClientMethod(grpc_generator::Printer *printer, - const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars, - bool is_public) { - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - struct { - 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", "", ""}}; - - if (is_public) { - if (method->NoStreaming()) { - printer->Print( - *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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - printer->Print( - *vars, - "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> " - "$AsyncPrefix$$Method$(::grpc::ClientContext* context, " - "const $Request$& request, " - "::grpc::CompletionQueue* cq) {\n"); - printer->Indent(); - printer->Print(*vars, - "return std::unique_ptr< " - "::grpc::ClientAsyncResponseReader< $Response$>>(" - "$AsyncPrefix$$Method$Raw(context, request, cq));\n"); - printer->Outdent(); - printer->Print("}\n"); - } - } else if (ClientOnlyStreaming(method)) { - printer->Print( - *vars, - "std::unique_ptr< ::grpc::ClientWriter< $Request$>>" - " $Method$(" - "::grpc::ClientContext* context, $Response$* response) {\n"); - printer->Indent(); - printer->Print(*vars, - "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>" - "($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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncRawArgs"] = async_prefix.raw_args; - printer->Print(*vars, - "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>" - " $AsyncPrefix$$Method$(::grpc::ClientContext* context, " - "$Response$* response, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>(" - "$AsyncPrefix$$Method$Raw(context, response, " - "cq$AsyncRawArgs$));\n"); - printer->Outdent(); - printer->Print("}\n"); - } - } else if (ServerOnlyStreaming(method)) { - printer->Print( - *vars, - "std::unique_ptr< ::grpc::ClientReader< $Response$>>" - " $Method$(::grpc::ClientContext* context, const $Request$& request)" - " {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< ::grpc::ClientReader< $Response$>>" - "($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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncRawArgs"] = async_prefix.raw_args; - printer->Print( - *vars, - "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> " - "$AsyncPrefix$$Method$(" - "::grpc::ClientContext* context, const $Request$& request, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>(" - "$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n"); - printer->Outdent(); - printer->Print("}\n"); - } - } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>" - " $Method$(::grpc::ClientContext* context) {\n"); - printer->Indent(); - printer->Print(*vars, - "return std::unique_ptr< " - "::grpc::ClientReaderWriter< $Request$, $Response$>>(" - "$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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncRawArgs"] = async_prefix.raw_args; - printer->Print(*vars, - "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< " - "$Request$, $Response$>> " - "$AsyncPrefix$$Method$(::grpc::ClientContext* context, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); - printer->Indent(); - printer->Print( - *vars, - "return std::unique_ptr< " - "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>(" - "$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n"); - printer->Outdent(); - printer->Print("}\n"); - } - } - } else { - if (method->NoStreaming()) { - 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, - "::grpc::ClientAsyncResponseReader< $Response$>* " - "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, " - "const $Request$& request, " - "::grpc::CompletionQueue* cq) override;\n"); - } - } else if (ClientOnlyStreaming(method)) { - printer->Print(*vars, - "::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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncRawArgs"] = async_prefix.raw_args; - printer->Print( - *vars, - "::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw(" - "::grpc::ClientContext* context, $Response$* response, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n"); - } - } else if (ServerOnlyStreaming(method)) { - printer->Print(*vars, - "::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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncRawArgs"] = async_prefix.raw_args; - printer->Print( - *vars, - "::grpc::ClientAsyncReader< $Response$>* $AsyncPrefix$$Method$Raw(" - "::grpc::ClientContext* context, const $Request$& request, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n"); - } - } else if (method->BidiStreaming()) { - 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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncRawArgs"] = async_prefix.raw_args; - printer->Print( - *vars, - "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* " - "$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n"); - } - } - } -} - -void PrintHeaderClientMethodData(grpc_generator::Printer *printer, - const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Method"] = method->name(); - printer->Print(*vars, - "const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n"); -} - -void PrintHeaderServerMethodSync(grpc_generator::Printer *printer, - const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - printer->Print(method->GetLeadingComments("//").c_str()); - if (method->NoStreaming()) { - printer->Print(*vars, - "virtual ::grpc::Status $Method$(" - "::grpc::ServerContext* context, const $Request$* request, " - "$Response$* response);\n"); - } else if (ClientOnlyStreaming(method)) { - printer->Print(*vars, - "virtual ::grpc::Status $Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerReader< $Request$>* reader, " - "$Response$* response);\n"); - } else if (ServerOnlyStreaming(method)) { - printer->Print(*vars, - "virtual ::grpc::Status $Method$(" - "::grpc::ServerContext* context, const $Request$* request, " - "::grpc::ServerWriter< $Response$>* writer);\n"); - } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "virtual ::grpc::Status $Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);" - "\n"); - } - printer->Print(method->GetTrailingComments("//").c_str()); -} - -void PrintHeaderServerMethodAsync(grpc_generator::Printer *printer, - const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - printer->Print(*vars, "template <class BaseClass>\n"); - printer->Print(*vars, - "class WithAsyncMethod_$Method$ : public BaseClass {\n"); - printer->Print( - " private:\n" - " void BaseClassMustBeDerivedFromService(const Service *service) {}\n"); - printer->Print(" public:\n"); - printer->Indent(); - printer->Print(*vars, - "WithAsyncMethod_$Method$() {\n" - " ::grpc::Service::MarkMethodAsync($Idx$);\n" - "}\n"); - printer->Print(*vars, - "~WithAsyncMethod_$Method$() override {\n" - " BaseClassMustBeDerivedFromService(this);\n" - "}\n"); - if (method->NoStreaming()) { - printer->Print( - *vars, - "// disable synchronous version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, const $Request$* request, " - "$Response$* response) final override {\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - printer->Print( - *vars, - "void Request$Method$(" - "::grpc::ServerContext* context, $Request$* request, " - "::grpc::ServerAsyncResponseWriter< $Response$>* response, " - "::grpc::CompletionQueue* new_call_cq, " - "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n"); - printer->Print(*vars, - " ::grpc::Service::RequestAsyncUnary($Idx$, context, " - "request, response, new_call_cq, notification_cq, tag);\n"); - printer->Print("}\n"); - } else if (ClientOnlyStreaming(method)) { - printer->Print( - *vars, - "// disable synchronous version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerReader< $Request$>* reader, " - "$Response$* response) final override {\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - printer->Print( - *vars, - "void Request$Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, " - "::grpc::CompletionQueue* new_call_cq, " - "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n"); - printer->Print(*vars, - " ::grpc::Service::RequestAsyncClientStreaming($Idx$, " - "context, reader, new_call_cq, notification_cq, tag);\n"); - printer->Print("}\n"); - } else if (ServerOnlyStreaming(method)) { - printer->Print( - *vars, - "// disable synchronous version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, const $Request$* request, " - "::grpc::ServerWriter< $Response$>* writer) final override " - "{\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - printer->Print( - *vars, - "void Request$Method$(" - "::grpc::ServerContext* context, $Request$* request, " - "::grpc::ServerAsyncWriter< $Response$>* writer, " - "::grpc::CompletionQueue* new_call_cq, " - "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n"); - printer->Print( - *vars, - " ::grpc::Service::RequestAsyncServerStreaming($Idx$, " - "context, request, writer, new_call_cq, notification_cq, tag);\n"); - printer->Print("}\n"); - } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "// disable synchronous version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) " - "final override {\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - printer->Print( - *vars, - "void Request$Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, " - "::grpc::CompletionQueue* new_call_cq, " - "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n"); - printer->Print(*vars, - " ::grpc::Service::RequestAsyncBidiStreaming($Idx$, " - "context, stream, new_call_cq, notification_cq, tag);\n"); - printer->Print("}\n"); - } - printer->Outdent(); - printer->Print(*vars, "};\n"); -} - -void PrintHeaderServerMethodStreamedUnary( - grpc_generator::Printer *printer, const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - if (method->NoStreaming()) { - printer->Print(*vars, "template <class BaseClass>\n"); - printer->Print(*vars, - "class WithStreamedUnaryMethod_$Method$ : " - "public BaseClass {\n"); - printer->Print( - " private:\n" - " void BaseClassMustBeDerivedFromService(const Service *service) " - "{}\n"); - printer->Print(" public:\n"); - printer->Indent(); - printer->Print(*vars, - "WithStreamedUnaryMethod_$Method$() {\n" - " ::grpc::Service::MarkMethodStreamed($Idx$,\n" - " new ::grpc::internal::StreamedUnaryHandler< $Request$, " - "$Response$>(std::bind" - "(&WithStreamedUnaryMethod_$Method$<BaseClass>::" - "Streamed$Method$, this, std::placeholders::_1, " - "std::placeholders::_2)));\n" - "}\n"); - printer->Print(*vars, - "~WithStreamedUnaryMethod_$Method$() override {\n" - " BaseClassMustBeDerivedFromService(this);\n" - "}\n"); - printer->Print( - *vars, - "// disable regular version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, const $Request$* request, " - "$Response$* response) final override {\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - printer->Print(*vars, - "// replace default version of method with streamed unary\n" - "virtual ::grpc::Status Streamed$Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerUnaryStreamer< " - "$Request$,$Response$>* server_unary_streamer)" - " = 0;\n"); - printer->Outdent(); - printer->Print(*vars, "};\n"); - } -} - -void PrintHeaderServerMethodSplitStreaming( - grpc_generator::Printer *printer, const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - if (ServerOnlyStreaming(method)) { - printer->Print(*vars, "template <class BaseClass>\n"); - printer->Print(*vars, - "class WithSplitStreamingMethod_$Method$ : " - "public BaseClass {\n"); - printer->Print( - " private:\n" - " void BaseClassMustBeDerivedFromService(const Service *service) " - "{}\n"); - printer->Print(" public:\n"); - printer->Indent(); - printer->Print( - *vars, - "WithSplitStreamingMethod_$Method$() {\n" - " ::grpc::Service::MarkMethodStreamed($Idx$,\n" - " new ::grpc::internal::SplitServerStreamingHandler< $Request$, " - "$Response$>(std::bind" - "(&WithSplitStreamingMethod_$Method$<BaseClass>::" - "Streamed$Method$, this, std::placeholders::_1, " - "std::placeholders::_2)));\n" - "}\n"); - printer->Print(*vars, - "~WithSplitStreamingMethod_$Method$() override {\n" - " BaseClassMustBeDerivedFromService(this);\n" - "}\n"); - printer->Print( - *vars, - "// disable regular version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, const $Request$* request, " - "::grpc::ServerWriter< $Response$>* writer) final override " - "{\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - printer->Print(*vars, - "// replace default version of method with split streamed\n" - "virtual ::grpc::Status Streamed$Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerSplitStreamer< " - "$Request$,$Response$>* server_split_streamer)" - " = 0;\n"); - printer->Outdent(); - printer->Print(*vars, "};\n"); - } -} - -void PrintHeaderServerMethodGeneric( - grpc_generator::Printer *printer, const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - printer->Print(*vars, "template <class BaseClass>\n"); - printer->Print(*vars, - "class WithGenericMethod_$Method$ : public BaseClass {\n"); - printer->Print( - " private:\n" - " void BaseClassMustBeDerivedFromService(const Service *service) {}\n"); - printer->Print(" public:\n"); - printer->Indent(); - printer->Print(*vars, - "WithGenericMethod_$Method$() {\n" - " ::grpc::Service::MarkMethodGeneric($Idx$);\n" - "}\n"); - printer->Print(*vars, - "~WithGenericMethod_$Method$() override {\n" - " BaseClassMustBeDerivedFromService(this);\n" - "}\n"); - if (method->NoStreaming()) { - printer->Print( - *vars, - "// disable synchronous version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, const $Request$* request, " - "$Response$* response) final override {\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - } else if (ClientOnlyStreaming(method)) { - printer->Print( - *vars, - "// disable synchronous version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerReader< $Request$>* reader, " - "$Response$* response) final override {\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - } else if (ServerOnlyStreaming(method)) { - printer->Print( - *vars, - "// disable synchronous version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, const $Request$* request, " - "::grpc::ServerWriter< $Response$>* writer) final override " - "{\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "// disable synchronous version of this method\n" - "::grpc::Status $Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) " - "final override {\n" - " abort();\n" - " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" - "}\n"); - } - printer->Outdent(); - printer->Print(*vars, "};\n"); -} - -void PrintHeaderService(grpc_generator::Printer *printer, - const grpc_generator::Service *service, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Service"] = service->name(); - - printer->Print(service->GetLeadingComments("//").c_str()); - printer->Print(*vars, - "class $Service$ final {\n" - " public:\n"); - printer->Indent(); - - // Service metadata - printer->Print(*vars, - "static constexpr char const* service_full_name() {\n" - " return \"$Package$$Service$\";\n" - "}\n"); - - // Client side - printer->Print( - "class StubInterface {\n" - " public:\n"); - printer->Indent(); - printer->Print("virtual ~StubInterface() {}\n"); - for (int i = 0; i < service->method_count(); ++i) { - printer->Print(service->method(i)->GetLeadingComments("//").c_str()); - PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars, - true); - printer->Print(service->method(i)->GetTrailingComments("//").c_str()); - } - printer->Outdent(); - printer->Print("private:\n"); - printer->Indent(); - for (int i = 0; i < service->method_count(); ++i) { - PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars, - false); - } - printer->Outdent(); - printer->Print("};\n"); - printer->Print( - "class Stub final : public StubInterface" - " {\n public:\n"); - printer->Indent(); - printer->Print( - "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& " - "channel);\n"); - for (int i = 0; i < service->method_count(); ++i) { - PrintHeaderClientMethod(printer, service->method(i).get(), vars, true); - } - printer->Outdent(); - printer->Print("\n private:\n"); - printer->Indent(); - printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n"); - for (int i = 0; i < service->method_count(); ++i) { - PrintHeaderClientMethod(printer, service->method(i).get(), vars, false); - } - for (int i = 0; i < service->method_count(); ++i) { - PrintHeaderClientMethodData(printer, service->method(i).get(), vars); - } - printer->Outdent(); - printer->Print("};\n"); - printer->Print( - "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< " - "::grpc::ChannelInterface>& channel, " - "const ::grpc::StubOptions& options = ::grpc::StubOptions());\n"); - - printer->Print("\n"); - - // Server side - base - printer->Print( - "class Service : public ::grpc::Service {\n" - " public:\n"); - printer->Indent(); - printer->Print("Service();\n"); - printer->Print("virtual ~Service();\n"); - for (int i = 0; i < service->method_count(); ++i) { - PrintHeaderServerMethodSync(printer, service->method(i).get(), vars); - } - printer->Outdent(); - printer->Print("};\n"); - - // Server side - Asynchronous - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["Idx"] = as_string(i); - PrintHeaderServerMethodAsync(printer, service->method(i).get(), vars); - } - - printer->Print("typedef "); - - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["method_name"] = service->method(i).get()->name(); - printer->Print(*vars, "WithAsyncMethod_$method_name$<"); - } - printer->Print("Service"); - for (int i = 0; i < service->method_count(); ++i) { - printer->Print(" >"); - } - printer->Print(" AsyncService;\n"); - - // Server side - Generic - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["Idx"] = as_string(i); - PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars); - } - - // Server side - Streamed Unary - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["Idx"] = as_string(i); - PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(), - vars); - } - - printer->Print("typedef "); - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["method_name"] = service->method(i).get()->name(); - if (service->method(i)->NoStreaming()) { - printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<"); - } - } - printer->Print("Service"); - for (int i = 0; i < service->method_count(); ++i) { - if (service->method(i)->NoStreaming()) { - printer->Print(" >"); - } - } - printer->Print(" StreamedUnaryService;\n"); - - // Server side - controlled server-side streaming - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["Idx"] = as_string(i); - PrintHeaderServerMethodSplitStreaming(printer, service->method(i).get(), - vars); - } - - printer->Print("typedef "); - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["method_name"] = service->method(i).get()->name(); - auto method = service->method(i); - if (ServerOnlyStreaming(method.get())) { - printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<"); - } - } - printer->Print("Service"); - for (int i = 0; i < service->method_count(); ++i) { - auto method = service->method(i); - if (ServerOnlyStreaming(method.get())) { - printer->Print(" >"); - } - } - printer->Print(" SplitStreamedService;\n"); - - // Server side - typedef for controlled both unary and server-side streaming - printer->Print("typedef "); - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["method_name"] = service->method(i).get()->name(); - auto method = service->method(i); - if (ServerOnlyStreaming(method.get())) { - printer->Print(*vars, "WithSplitStreamingMethod_$method_name$<"); - } - if (service->method(i)->NoStreaming()) { - printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<"); - } - } - printer->Print("Service"); - for (int i = 0; i < service->method_count(); ++i) { - auto method = service->method(i); - if (service->method(i)->NoStreaming() || - ServerOnlyStreaming(method.get())) { - printer->Print(" >"); - } - } - printer->Print(" StreamedService;\n"); - - printer->Outdent(); - printer->Print("};\n"); - printer->Print(service->GetTrailingComments("//").c_str()); -} - -grpc::string GetHeaderServices(grpc_generator::File *file, - const Parameters ¶ms) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - std::map<grpc::string, grpc::string> vars; - // 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 (!params.services_namespace.empty()) { - vars["services_namespace"] = params.services_namespace; - printer->Print(vars, "\nnamespace $services_namespace$ {\n\n"); - } - - for (int i = 0; i < file->service_count(); ++i) { - PrintHeaderService(printer.get(), file->service(i).get(), &vars); - printer->Print("\n"); - } - - if (!params.services_namespace.empty()) { - printer->Print(vars, "} // namespace $services_namespace$\n\n"); - } - } - return output; -} - -grpc::string GetHeaderEpilogue(grpc_generator::File *file, - const Parameters & /*params*/) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - std::map<grpc::string, grpc::string> vars; - - vars["filename"] = file->filename(); - vars["filename_identifier"] = FilenameIdentifier(file->filename()); - - if (!file->package().empty()) { - std::vector<grpc::string> parts = file->package_parts(); - - for (auto part = parts.rbegin(); part != parts.rend(); part++) { - vars["part"] = *part; - printer->Print(vars, "} // namespace $part$\n"); - } - printer->Print(vars, "\n"); - } - - printer->Print(vars, "\n"); - printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n"); - - printer->Print(file->GetTrailingComments("//").c_str()); - } - return output; -} - -grpc::string GetSourcePrologue(grpc_generator::File *file, - const Parameters & /*params*/) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - std::map<grpc::string, grpc::string> vars; - - vars["filename"] = file->filename(); - vars["filename_base"] = file->filename_without_ext(); - vars["message_header_ext"] = message_header_ext(); - vars["service_header_ext"] = service_header_ext(); - - printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); - printer->Print(vars, - "// If you make any local change, they will be lost.\n"); - printer->Print(vars, "// source: $filename$\n\n"); - - printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n"); - printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n"); - printer->Print(vars, "\n"); - } - return output; -} - -grpc::string GetSourceIncludes(grpc_generator::File *file, - const Parameters ¶ms) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - 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"}; - std::vector<grpc::string> headers(headers_strs, array_end(headers_strs)); - PrintIncludes(printer.get(), headers, params); - - if (!file->package().empty()) { - std::vector<grpc::string> parts = file->package_parts(); - - for (auto part = parts.begin(); part != parts.end(); part++) { - vars["part"] = *part; - printer->Print(vars, "namespace $part$ {\n"); - } - } - - printer->Print(vars, "\n"); - } - return output; -} - -void PrintSourceClientMethod(grpc_generator::Printer *printer, - const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - struct { - grpc::string prefix; - 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"}}; - if (method->NoStreaming()) { - printer->Print(*vars, - "::grpc::Status $ns$$Service$::Stub::$Method$(" - "::grpc::ClientContext* context, " - "const $Request$& request, $Response$* response) {\n"); - printer->Print(*vars, - " 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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncStart"] = async_prefix.start; - printer->Print(*vars, - "::grpc::ClientAsyncResponseReader< $Response$>* " - "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::" - "ClientContext* context, " - "const $Request$& request, " - "::grpc::CompletionQueue* cq) {\n"); - printer->Print( - *vars, - " return " - "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>" - "::Create(channel_.get(), cq, " - "rpcmethod_$Method$_, " - "context, request, $AsyncStart$);\n" - "}\n\n"); - } - } else if (ClientOnlyStreaming(method)) { - printer->Print(*vars, - "::grpc::ClientWriter< $Request$>* " - "$ns$$Service$::Stub::$Method$Raw(" - "::grpc::ClientContext* context, $Response$* response) {\n"); - printer->Print( - *vars, - " return ::grpc::internal::ClientWriterFactory< $Request$>::Create(" - "channel_.get(), " - "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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncStart"] = async_prefix.start; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncCreateArgs"] = async_prefix.create_args; - printer->Print(*vars, - "::grpc::ClientAsyncWriter< $Request$>* " - "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(" - "::grpc::ClientContext* context, $Response$* response, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); - printer->Print( - *vars, - " return ::grpc::internal::ClientAsyncWriterFactory< $Request$>" - "::Create(channel_.get(), cq, " - "rpcmethod_$Method$_, " - "context, response, $AsyncStart$$AsyncCreateArgs$);\n" - "}\n\n"); - } - } else if (ServerOnlyStreaming(method)) { - printer->Print( - *vars, - "::grpc::ClientReader< $Response$>* " - "$ns$$Service$::Stub::$Method$Raw(" - "::grpc::ClientContext* context, const $Request$& request) {\n"); - printer->Print( - *vars, - " return ::grpc::internal::ClientReaderFactory< $Response$>::Create(" - "channel_.get(), " - "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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncStart"] = async_prefix.start; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncCreateArgs"] = async_prefix.create_args; - printer->Print( - *vars, - "::grpc::ClientAsyncReader< $Response$>* " - "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(" - "::grpc::ClientContext* context, const $Request$& request, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); - printer->Print( - *vars, - " return ::grpc::internal::ClientAsyncReaderFactory< $Response$>" - "::Create(channel_.get(), cq, " - "rpcmethod_$Method$_, " - "context, request, $AsyncStart$$AsyncCreateArgs$);\n" - "}\n\n"); - } - } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "::grpc::ClientReaderWriter< $Request$, $Response$>* " - "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n"); - printer->Print(*vars, - " return ::grpc::internal::ClientReaderWriterFactory< " - "$Request$, $Response$>::Create(" - "channel_.get(), " - "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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncStart"] = async_prefix.start; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["AsyncCreateArgs"] = async_prefix.create_args; - printer->Print(*vars, - "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* " - "$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::" - "ClientContext* context, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); - printer->Print(*vars, - " return " - "::grpc::internal::ClientAsyncReaderWriterFactory< " - "$Request$, $Response$>::Create(" - "channel_.get(), cq, " - "rpcmethod_$Method$_, " - "context, $AsyncStart$$AsyncCreateArgs$);\n" - "}\n\n"); - } - } -} - -void PrintSourceServerMethod(grpc_generator::Printer *printer, - const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Method"] = method->name(); - (*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(" (void) context;\n"); - printer->Print(" (void) request;\n"); - printer->Print(" (void) response;\n"); - printer->Print( - " return ::grpc::Status(" - "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); - printer->Print("}\n\n"); - } else if (ClientOnlyStreaming(method)) { - printer->Print(*vars, - "::grpc::Status $ns$$Service$::Service::$Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerReader< $Request$>* reader, " - "$Response$* response) {\n"); - printer->Print(" (void) context;\n"); - printer->Print(" (void) reader;\n"); - printer->Print(" (void) response;\n"); - printer->Print( - " return ::grpc::Status(" - "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); - printer->Print("}\n\n"); - } else if (ServerOnlyStreaming(method)) { - printer->Print(*vars, - "::grpc::Status $ns$$Service$::Service::$Method$(" - "::grpc::ServerContext* context, " - "const $Request$* request, " - "::grpc::ServerWriter< $Response$>* writer) {\n"); - printer->Print(" (void) context;\n"); - printer->Print(" (void) request;\n"); - printer->Print(" (void) writer;\n"); - printer->Print( - " return ::grpc::Status(" - "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); - printer->Print("}\n\n"); - } else if (method->BidiStreaming()) { - printer->Print(*vars, - "::grpc::Status $ns$$Service$::Service::$Method$(" - "::grpc::ServerContext* context, " - "::grpc::ServerReaderWriter< $Response$, $Request$>* " - "stream) {\n"); - printer->Print(" (void) context;\n"); - printer->Print(" (void) stream;\n"); - printer->Print( - " return ::grpc::Status(" - "::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"); - printer->Print("}\n\n"); - } -} - -void PrintSourceService(grpc_generator::Printer *printer, - const grpc_generator::Service *service, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Service"] = service->name(); - - if (service->method_count() > 0) { - printer->Print(*vars, - "static const char* $prefix$$Service$_method_names[] = {\n"); - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["Method"] = service->method(i).get()->name(); - printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n"); - } - printer->Print(*vars, "};\n\n"); - } - - printer->Print(*vars, - "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub(" - "const std::shared_ptr< ::grpc::ChannelInterface>& channel, " - "const ::grpc::StubOptions& options) {\n" - " std::unique_ptr< $ns$$Service$::Stub> stub(new " - "$ns$$Service$::Stub(channel));\n" - " return stub;\n" - "}\n\n"); - printer->Print(*vars, - "$ns$$Service$::Stub::Stub(const std::shared_ptr< " - "::grpc::ChannelInterface>& channel)\n"); - printer->Indent(); - printer->Print(": channel_(channel)"); - for (int i = 0; i < service->method_count(); ++i) { - auto method = service->method(i); - (*vars)["Method"] = method->name(); - (*vars)["Idx"] = as_string(i); - if (method->NoStreaming()) { - (*vars)["StreamingType"] = "NORMAL_RPC"; - // NOTE: There is no reason to consider streamed-unary as a separate - // category here since this part is setting up the client-side stub - // and this appears as a NORMAL_RPC from the client-side. - } else if (ClientOnlyStreaming(method.get())) { - (*vars)["StreamingType"] = "CLIENT_STREAMING"; - } else if (ServerOnlyStreaming(method.get())) { - (*vars)["StreamingType"] = "SERVER_STREAMING"; - } else { - (*vars)["StreamingType"] = "BIDI_STREAMING"; - } - printer->Print(*vars, - ", rpcmethod_$Method$_(" - "$prefix$$Service$_method_names[$Idx$], " - "::grpc::internal::RpcMethod::$StreamingType$, " - "channel" - ")\n"); - } - printer->Print("{}\n\n"); - printer->Outdent(); - - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["Idx"] = as_string(i); - PrintSourceClientMethod(printer, service->method(i).get(), vars); - } - - printer->Print(*vars, "$ns$$Service$::Service::Service() {\n"); - printer->Indent(); - for (int i = 0; i < service->method_count(); ++i) { - auto method = service->method(i); - (*vars)["Idx"] = as_string(i); - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - if (method->NoStreaming()) { - printer->Print( - *vars, - "AddMethod(new ::grpc::internal::RpcServiceMethod(\n" - " $prefix$$Service$_method_names[$Idx$],\n" - " ::grpc::internal::RpcMethod::NORMAL_RPC,\n" - " new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, " - "$Request$, " - "$Response$>(\n" - " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); - } else if (ClientOnlyStreaming(method.get())) { - printer->Print( - *vars, - "AddMethod(new ::grpc::internal::RpcServiceMethod(\n" - " $prefix$$Service$_method_names[$Idx$],\n" - " ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n" - " new ::grpc::internal::ClientStreamingHandler< " - "$ns$$Service$::Service, $Request$, $Response$>(\n" - " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); - } else if (ServerOnlyStreaming(method.get())) { - printer->Print( - *vars, - "AddMethod(new ::grpc::internal::RpcServiceMethod(\n" - " $prefix$$Service$_method_names[$Idx$],\n" - " ::grpc::internal::RpcMethod::SERVER_STREAMING,\n" - " new ::grpc::internal::ServerStreamingHandler< " - "$ns$$Service$::Service, $Request$, $Response$>(\n" - " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); - } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "AddMethod(new ::grpc::internal::RpcServiceMethod(\n" - " $prefix$$Service$_method_names[$Idx$],\n" - " ::grpc::internal::RpcMethod::BIDI_STREAMING,\n" - " new ::grpc::internal::BidiStreamingHandler< " - "$ns$$Service$::Service, $Request$, $Response$>(\n" - " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); - } - } - printer->Outdent(); - printer->Print(*vars, "}\n\n"); - printer->Print(*vars, - "$ns$$Service$::Service::~Service() {\n" - "}\n\n"); - for (int i = 0; i < service->method_count(); ++i) { - (*vars)["Idx"] = as_string(i); - PrintSourceServerMethod(printer, service->method(i).get(), vars); - } -} - -grpc::string GetSourceServices(grpc_generator::File *file, - const Parameters ¶ms) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - std::map<grpc::string, grpc::string> vars; - // 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 (!params.services_namespace.empty()) { - vars["ns"] = params.services_namespace + "::"; - vars["prefix"] = params.services_namespace; - } else { - vars["ns"] = ""; - vars["prefix"] = ""; - } - - for (int i = 0; i < file->service_count(); ++i) { - PrintSourceService(printer.get(), file->service(i).get(), &vars); - printer->Print("\n"); - } - } - return output; -} - -grpc::string GetSourceEpilogue(grpc_generator::File *file, - const Parameters & /*params*/) { - grpc::string temp; - - if (!file->package().empty()) { - std::vector<grpc::string> parts = file->package_parts(); - - for (auto part = parts.begin(); part != parts.end(); part++) { - temp.append("} // namespace "); - temp.append(*part); - temp.append("\n"); - } - temp.append("\n"); - } - - return temp; -} - -// TODO(mmukhi): Make sure we need parameters or not. -grpc::string GetMockPrologue(grpc_generator::File *file, - const Parameters & /*params*/) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - std::map<grpc::string, grpc::string> vars; - - vars["filename"] = file->filename(); - vars["filename_base"] = file->filename_without_ext(); - vars["message_header_ext"] = message_header_ext(); - vars["service_header_ext"] = service_header_ext(); - - printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); - printer->Print(vars, - "// If you make any local change, they will be lost.\n"); - printer->Print(vars, "// source: $filename$\n\n"); - - printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n"); - printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n"); - printer->Print(vars, file->additional_headers().c_str()); - printer->Print(vars, "\n"); - } - return output; -} - -// TODO(mmukhi): Add client-stream and completion-queue headers. -grpc::string GetMockIncludes(grpc_generator::File *file, - const Parameters ¶ms) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - 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", - }; - std::vector<grpc::string> headers(headers_strs, array_end(headers_strs)); - PrintIncludes(printer.get(), headers, params); - - if (!file->package().empty()) { - std::vector<grpc::string> parts = file->package_parts(); - - for (auto part = parts.begin(); part != parts.end(); part++) { - vars["part"] = *part; - printer->Print(vars, "namespace $part$ {\n"); - } - } - - printer->Print(vars, "\n"); - } - return output; -} - -void PrintMockClientMethods(grpc_generator::Printer *printer, - const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Method"] = method->name(); - (*vars)["Request"] = method->input_type_name(); - (*vars)["Response"] = method->output_type_name(); - - struct { - grpc::string prefix; - grpc::string method_params; // extra arguments to method - int extra_method_param_count; - } 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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - printer->Print( - *vars, - "MOCK_METHOD3($AsyncPrefix$$Method$Raw, " - "::grpc::ClientAsyncResponseReaderInterface< $Response$>*" - "(::grpc::ClientContext* context, const $Request$& request, " - "::grpc::CompletionQueue* cq));\n"); - } - } else if (ClientOnlyStreaming(method)) { - printer->Print( - *vars, - "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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["MockArgs"] = - flatbuffers::NumToString(3 + async_prefix.extra_method_param_count); - printer->Print(*vars, - "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, " - "::grpc::ClientAsyncWriterInterface< $Request$>*" - "(::grpc::ClientContext* context, $Response$* response, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n"); - } - } else if (ServerOnlyStreaming(method)) { - printer->Print( - *vars, - "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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["MockArgs"] = - flatbuffers::NumToString(3 + async_prefix.extra_method_param_count); - printer->Print( - *vars, - "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, " - "::grpc::ClientAsyncReaderInterface< $Response$>*" - "(::grpc::ClientContext* context, const $Request$& request, " - "::grpc::CompletionQueue* cq$AsyncMethodParams$));\n"); - } - } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "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]; - (*vars)["AsyncPrefix"] = async_prefix.prefix; - (*vars)["AsyncMethodParams"] = async_prefix.method_params; - (*vars)["MockArgs"] = - flatbuffers::NumToString(2 + async_prefix.extra_method_param_count); - printer->Print( - *vars, - "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, " - "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*" - "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq" - "$AsyncMethodParams$));\n"); - } - } -} - -void PrintMockService(grpc_generator::Printer *printer, - const grpc_generator::Service *service, - std::map<grpc::string, grpc::string> *vars) { - (*vars)["Service"] = service->name(); - - printer->Print(*vars, - "class Mock$Service$Stub : public $Service$::StubInterface {\n" - " public:\n"); - printer->Indent(); - for (int i = 0; i < service->method_count(); ++i) { - PrintMockClientMethods(printer, service->method(i).get(), vars); - } - printer->Outdent(); - printer->Print("};\n"); -} - -grpc::string GetMockServices(grpc_generator::File *file, - const Parameters ¶ms) { - grpc::string output; - { - // Scope the output stream so it closes and finalizes output to the string. - auto printer = file->CreatePrinter(&output); - std::map<grpc::string, grpc::string> vars; - // 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 (!params.services_namespace.empty()) { - vars["services_namespace"] = params.services_namespace; - printer->Print(vars, "\nnamespace $services_namespace$ {\n\n"); - } - - for (int i = 0; i < file->service_count(); i++) { - PrintMockService(printer.get(), file->service(i).get(), &vars); - printer->Print("\n"); - } - - if (!params.services_namespace.empty()) { - printer->Print(vars, "} // namespace $services_namespace$\n\n"); - } - } - return output; -} - -grpc::string GetMockEpilogue(grpc_generator::File *file, - const Parameters & /*params*/) { - grpc::string temp; - - if (!file->package().empty()) { - std::vector<grpc::string> parts = file->package_parts(); - - for (auto part = parts.begin(); part != parts.end(); part++) { - temp.append("} // namespace "); - temp.append(*part); - temp.append("\n"); - } - temp.append("\n"); - } - - return temp; -} - -} // namespace grpc_cpp_generator diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/cpp_generator.h b/contrib/libs/flatbuffers/grpc/src/compiler/cpp_generator.h deleted file mode 100644 index 6119ebe289..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/cpp_generator.h +++ /dev/null @@ -1,138 +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 GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H -#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H - -// cpp_generator.h/.cc do not directly depend on GRPC/ProtoBuf, such that they -// can be used to generate code for other serialization systems, such as -// FlatBuffers. - -#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 -#endif - -namespace grpc { - -typedef GRPC_CUSTOM_STRING string; - -} // namespace grpc - -namespace grpc_cpp_generator { - -// Contains all the parameters that are parsed from the command line. -struct Parameters { - // Puts the service into a namespace - grpc::string services_namespace; - // Use system includes (<>) or local includes ("") - bool use_system_headers; - // Prefix to any grpc include - grpc::string grpc_search_path; - // Generate GMOCK code to facilitate unit testing. - bool generate_mock_code; -}; - -// Return the prologue of the generated header file. -grpc::string GetHeaderPrologue(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the includes needed for generated header file. -grpc::string GetHeaderIncludes(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the includes needed for generated source file. -grpc::string GetSourceIncludes(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the epilogue of the generated header file. -grpc::string GetHeaderEpilogue(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the prologue of the generated source file. -grpc::string GetSourcePrologue(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the services for generated header file. -grpc::string GetHeaderServices(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the services for generated source file. -grpc::string GetSourceServices(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the epilogue of the generated source file. -grpc::string GetSourceEpilogue(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the prologue of the generated mock file. -grpc::string GetMockPrologue(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the includes needed for generated mock file. -grpc::string GetMockIncludes(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the services for generated mock file. -grpc::string GetMockServices(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the epilogue of generated mock file. -grpc::string GetMockEpilogue(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the prologue of the generated mock file. -grpc::string GetMockPrologue(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the includes needed for generated mock file. -grpc::string GetMockIncludes(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the services for generated mock file. -grpc::string GetMockServices(grpc_generator::File *file, - const Parameters ¶ms); - -// Return the epilogue of generated mock file. -grpc::string GetMockEpilogue(grpc_generator::File *file, - const Parameters ¶ms); - -} // namespace grpc_cpp_generator - -#endif // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/go_generator.cc b/contrib/libs/flatbuffers/grpc/src/compiler/go_generator.cc deleted file mode 100644 index d646451aa6..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/go_generator.cc +++ /dev/null @@ -1,501 +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 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(); -} - -inline bool ClientOnlyStreaming(const grpc_generator::Method *method) { - return method->ClientStreaming() && !method->ServerStreaming(); -} - -inline bool ServerOnlyStreaming(const grpc_generator::Method *method) { - return !method->ClientStreaming() && method->ServerStreaming(); -} - -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; -} - -// 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; -} - -void GenerateError(grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> vars, - const bool multiple_return = true) { - printer->Print(vars, "if $Error_Check$ {\n"); - printer->Indent(); - vars["Return"] = multiple_return ? "nil, err" : "err"; - printer->Print(vars, "return $Return$\n"); - printer->Outdent(); - printer->Print("}\n"); -} - -// Generates imports for the service -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"); - printer->Print("flatbuffers \"github.com/google/flatbuffers/go\"\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"); -} - -// Generates Server method signature source -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$"); - } -} - -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["Error_Check"] = "err := dec(in); err != nil"; - GenerateError(printer, vars); - printer->Print("if interceptor == nil {\n"); - printer->Indent(); - 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->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"); - 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"); - - 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 $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"); - 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"); - } - -} - -// Generates Client method signature source -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$"); -} - -// Generates Client method source -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) "); - 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"); - 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"); - vars["Error_Check"] = "err != nil"; - GenerateError(printer, vars); - - 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"); - - 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 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 (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"); - } - - 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"); - 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"); - } -} - -// Generates client API for the service -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["Ending"] = "\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"); - - // 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); - } - - //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); - } - printer->Print(vars, "mustEmbedUnimplemented$Service$Server()\n"); - printer->Outdent(); - printer->Print("}\n\n"); - - printer->Print(vars, "type Unimplemented$Service$Server struct {\n"); - printer->Print("}\n\n"); - - vars["Ending"] = " {\n"; - for (int i = 0; i < service->method_count(); i++) { - auto method = service->method(i); - vars["Method"] = exportName(method->name()); - vars["Nil"] = method->NoStreaming() ? "nil, " : ""; - 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->Outdent(); - printer->Print("}\n"); - printer->Print("\n"); - } - - printer->Print(vars, "func (Unimplemented$Service$Server) mustEmbedUnimplemented$Service$Server() {}"); - printer->Print("\n\n"); - - printer->Print(vars, "type Unsafe$Service$Server interface {\n"); - printer->Indent(); - 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"); - - 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'); - 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; -} -}// Namespace grpc_go_generator diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/go_generator.h b/contrib/libs/flatbuffers/grpc/src/compiler/go_generator.h deleted file mode 100644 index baa94e0599..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/go_generator.h +++ /dev/null @@ -1,64 +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 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 -#include <memory> -#include <vector> - -#include "src/compiler/schema_interface.h" - -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 - grpc::string custom_method_io_type; - - //Package name for the service - grpc::string package_name; - - //Prefix for RPC Calls - grpc::string service_prefix; -}; - -// Return the source of the generated service file. -grpc::string GenerateServiceSource(grpc_generator::File *file, - const grpc_generator::Service *service, - grpc_go_generator::Parameters *parameters); - -} - -#endif // GRPC_INTERNAL_COMPILER_GO_GENERATOR_H diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/java_generator.cc b/contrib/libs/flatbuffers/grpc/src/compiler/java_generator.cc deleted file mode 100644 index d2cf5ccc14..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/java_generator.cc +++ /dev/null @@ -1,1135 +0,0 @@ -/* - * Copyright 2016 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 - * - * 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 "src/compiler/java_generator.h" - -#include <algorithm> -#include <iostream> -#include <iterator> -#include <map> -#include <utility> -#include <vector> - -// just to get flatbuffer_version_string() -#include <flatbuffers/flatbuffers.h> -#include <flatbuffers/util.h> -#define to_string flatbuffers::NumToString - -// Stringify helpers used solely to cast GRPC_VERSION -#ifndef STR -#define STR(s) #s -#endif - -#ifndef XSTR -#define XSTR(s) STR(s) -#endif - - -typedef grpc_generator::Printer Printer; -typedef std::map<grpc::string, grpc::string> VARS; -typedef grpc_generator::Service ServiceDescriptor; -typedef grpc_generator::CommentHolder - DescriptorType; // base class of all 'descriptors' -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) { - vars["filename"] = file->filename(); - 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"); - vars["Package"] = vars["Package"] + "."; - if (!file->additional_headers().empty()) { - printer->Print(file->additional_headers().c_str()); - printer->Print("\n\n"); - } -} - -// 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) { - string w; - w += static_cast<string::value_type>(tolower(word[0])); - bool after_underscore = false; - for (size_t i = 1; i < word.length(); ++i) { - if (word[i] == '_') { - after_underscore = true; - } else { - w += after_underscore ? static_cast<string::value_type>(toupper(word[i])) - : word[i]; - after_underscore = false; - } - } - return w; -} - -// Converts to the identifier to the ALL_UPPER_CASE format. -// - 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) { - string w; - for (size_t i = 0; i < word.length(); ++i) { - w += static_cast<string::value_type>(toupper(word[i])); - if ((i < word.length() - 1) && islower(word[i]) && isupper(word[i + 1])) { - w += '_'; - } - } - return w; -} - -static inline string LowerMethodName(const MethodDescriptor* method) { - return MixedLower(method->name()); -} - -static inline string MethodPropertiesFieldName(const MethodDescriptor* method) { - return "METHOD_" + ToAllUpperCase(method->name()); -} - -static inline string MethodPropertiesGetterName( - const MethodDescriptor* method) { - return MixedLower("get_" + method->name() + "_method"); -} - -static inline string MethodIdFieldName(const MethodDescriptor* method) { - return "METHODID_" + ToAllUpperCase(method->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) { - 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) { - // 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(); - while (p != end) { - if (*p == c) { - ++p; - } else { - const char* start = p; - while (++p != end && *p != c) - ; - *result++ = string(start, p - start); - } - } - return; - } - - string::size_type begin_index, end_index; - begin_index = full.find_first_not_of(delim); - while (begin_index != string::npos) { - end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { - *result++ = full.substr(begin_index); - return; - } - *result++ = full.substr(begin_index, (end_index - begin_index)); - begin_index = full.find_first_not_of(delim, end_index); - } -} - -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) { - std::vector<string> result; - GrpcSplitStringUsing(full, delim, &result); - return result; -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in -// distribution. -static string GrpcEscapeJavadoc(const string& input) { - string result; - result.reserve(input.size() * 2); - - char prev = '*'; - - for (string::size_type i = 0; i < input.size(); i++) { - char c = input[i]; - switch (c) { - case '*': - // Avoid "/*". - if (prev == '/') { - result.append("*"); - } else { - result.push_back(c); - } - break; - case '/': - // Avoid "*/". - if (prev == '*') { - result.append("/"); - } else { - result.push_back(c); - } - break; - case '@': - // '@' starts javadoc tags including the @deprecated tag, which will - // cause a compile-time error if inserted before a declaration that - // does not have a corresponding @Deprecated annotation. - result.append("@"); - break; - case '<': - // Avoid interpretation as HTML. - result.append("<"); - break; - case '>': - // Avoid interpretation as HTML. - result.append(">"); - break; - case '&': - // Avoid interpretation as HTML. - result.append("&"); - break; - case '\\': - // Java interprets Unicode escape sequences anywhere! - result.append("\"); - break; - default: - result.push_back(c); - break; - } - - prev = c; - } - - return result; -} - -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 - // we just use <pre> to get fixed-width text formatting. - - // If the comment itself contains block comment start or end markers, - // HTML-escape them so that they don't accidentally close the doc comment. - string escapedComments = GrpcEscapeJavadoc(comments); - - std::vector<string> lines = GrpcSplit(escapedComments, "\n"); - while (!lines.empty() && lines.back().empty()) { - lines.pop_back(); - } - return lines; - } - return std::vector<string>(); -} - -static std::vector<string> GrpcGetDocLinesForDescriptor( - const DescriptorType* descriptor) { - return descriptor->GetAllComments(); - // return GrpcGetDocLines(descriptor->GetLeadingComments("///")); -} - -static void GrpcWriteDocCommentBody(Printer* printer, VARS& vars, - const std::vector<string>& lines, - bool surroundWithPreTag) { - if (!lines.empty()) { - 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 - // with a /, since putting that right after the leading asterisk will - // close the comment. - vars["line"] = lines[i]; - if (!lines[i].empty() && lines[i][0] == '/') { - printer->Print(vars, " * $line$\n"); - } else { - printer->Print(vars, " *$line$\n"); - } - } - - if (surroundWithPreTag) { - printer->Print(" * </pre>\n"); - } - } -} - -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) { - 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) { - 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"); -} -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 - 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_out_id"] = to_string(2L * i + 1); - vars["method_name"] = method->name(); - vars["input_type_name"] = method->get_input_type_name(); - vars["output_type_name"] = method->get_output_type_name(); - vars["input_type"] = JavaClassName(vars, method->get_input_type_name()); - vars["output_type"] = JavaClassName(vars, method->get_output_type_name()); - 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(); - if (client_streaming) { - if (server_streaming) { - vars["method_type"] = "BIDI_STREAMING"; - } else { - vars["method_type"] = "CLIENT_STREAMING"; - } - } else { - if (server_streaming) { - vars["method_type"] = "SERVER_STREAMING"; - } else { - vars["method_type"] = "UNARY"; - } - } - - p->Print( - vars, - "@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/" - "1901\")\n" - "@$Deprecated$ // Use {@link #$method_method_name$()} instead. \n" - "public static final $MethodDescriptor$<$input_type$,\n" - " $output_type$> $method_field_name$ = $method_method_name$();\n" - "\n" - "private static volatile $MethodDescriptor$<$input_type$,\n" - " $output_type$> $method_new_field_name$;\n" - "\n"); - - if (encounteredTypes.insert(vars["input_type_name"]).second) { - vars["extr_type"] = vars["input_type"]; - vars["extr_type_name"] = vars["input_type_name"]; - PrintTypeExtractor(p, vars); - } - - if (encounteredTypes.insert(vars["output_type_name"]).second) { - vars["extr_type"] = vars["output_type"]; - vars["extr_type_name"] = vars["output_type_name"]; - PrintTypeExtractor(p, 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["proto_method_descriptor_supplier"] = service->name() + - // "MethodDescriptorSupplier"; - p->Print(vars, " .setSchemaDescriptor(null)\n"); - //" .setSchemaDescriptor(new - //$proto_method_descriptor_supplier$(\"$method_name$\"))\n"); - - p->Print(vars, " .build();\n"); - p->Print(vars, - " }\n" - " }\n" - " }\n" - " return $method_new_field_name$;\n" - "}\n"); - - p->Print("\n"); - } -} -enum StubType { - ASYNC_INTERFACE = 0, - BLOCKING_CLIENT_INTERFACE = 1, - FUTURE_CLIENT_INTERFACE = 2, - BLOCKING_SERVER_INTERFACE = 3, - ASYNC_CLIENT_IMPL = 4, - BLOCKING_CLIENT_IMPL = 5, - FUTURE_CLIENT_IMPL = 6, - ABSTRACT_CLASS = 7, -}; - -enum CallType { ASYNC_CALL = 0, BLOCKING_CALL = 1, FUTURE_CALL = 2 }; - -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, - StubType type) { - const string service_name = service->name(); - vars["service_name"] = service_name; - vars["abstract_name"] = service_name + "ImplBase"; - string stub_name = service_name; - string client_name = service_name; - CallType call_type = ASYNC_CALL; - bool impl_base = false; - bool interface = false; - switch (type) { - case ABSTRACT_CLASS: - call_type = ASYNC_CALL; - impl_base = true; - break; - case ASYNC_CLIENT_IMPL: - call_type = ASYNC_CALL; - stub_name += "Stub"; - break; - case BLOCKING_CLIENT_INTERFACE: - interface = true; - FLATBUFFERS_FALLTHROUGH(); // fall thru - case BLOCKING_CLIENT_IMPL: - call_type = BLOCKING_CALL; - stub_name += "BlockingStub"; - client_name += "BlockingClient"; - break; - case FUTURE_CLIENT_INTERFACE: - interface = true; - FLATBUFFERS_FALLTHROUGH(); // fall thru - case FUTURE_CLIENT_IMPL: - call_type = FUTURE_CALL; - stub_name += "FutureStub"; - client_name += "FutureClient"; - break; - case ASYNC_INTERFACE: - call_type = ASYNC_CALL; - interface = true; - break; - default: - GRPC_CODEGEN_FAIL << "Cannot determine class name for StubType: " << type; - } - vars["stub_name"] = stub_name; - vars["client_name"] = client_name; - - // Class head - if (!interface) { - GrpcWriteServiceDocComment(p, vars, service); - } - if (impl_base) { - p->Print(vars, - "public static abstract class $abstract_name$ implements " - "$BindableService$ {\n"); - } else { - p->Print(vars, - "public static final class $stub_name$ extends " - "$AbstractStub$<$stub_name$> {\n"); - } - p->Indent(); - - // Constructor and build() method - if (!impl_base && !interface) { - p->Print(vars, "private $stub_name$($Channel$ channel) {\n"); - p->Indent(); - p->Print("super(channel);\n"); - p->Outdent(); - p->Print("}\n\n"); - p->Print(vars, - "private $stub_name$($Channel$ channel,\n" - " $CallOptions$ callOptions) {\n"); - p->Indent(); - p->Print("super(channel, callOptions);\n"); - p->Outdent(); - p->Print("}\n\n"); - p->Print(vars, - "@$Override$\n" - "protected $stub_name$ build($Channel$ channel,\n" - " $CallOptions$ callOptions) {\n"); - p->Indent(); - p->Print(vars, "return new $stub_name$(channel, callOptions);\n"); - p->Outdent(); - p->Print("}\n"); - } - - // RPC methods - for (int i = 0; i < service->method_count(); ++i) { - auto method = service->method(i); - vars["input_type"] = JavaClassName(vars, method->get_input_type_name()); - 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(); - - if (call_type == BLOCKING_CALL && client_streaming) { - // Blocking client interface with client streaming is not available - continue; - } - - if (call_type == FUTURE_CALL && (client_streaming || server_streaming)) { - // Future interface doesn't support streaming. - continue; - } - - // Method signature - p->Print("\n"); - // TODO(nmittler): Replace with WriteMethodDocComment once included by the - // protobuf distro. - if (!interface) { - GrpcWriteMethodDocComment(p, vars, &*method); - } - p->Print("public "); - switch (call_type) { - case BLOCKING_CALL: - GRPC_CODEGEN_CHECK(!client_streaming) - << "Blocking client interface with client streaming is unavailable"; - if (server_streaming) { - // Server streaming - p->Print(vars, - "$Iterator$<$output_type$> $lower_method_name$(\n" - " $input_type$ request)"); - } else { - // Simple RPC - p->Print(vars, - "$output_type$ $lower_method_name$($input_type$ request)"); - } - break; - case ASYNC_CALL: - if (client_streaming) { - // Bidirectional streaming or client streaming - p->Print(vars, - "$StreamObserver$<$input_type$> $lower_method_name$(\n" - " $StreamObserver$<$output_type$> responseObserver)"); - } else { - // Server streaming or simple RPC - p->Print(vars, - "void $lower_method_name$($input_type$ request,\n" - " $StreamObserver$<$output_type$> responseObserver)"); - } - break; - case FUTURE_CALL: - GRPC_CODEGEN_CHECK(!client_streaming && !server_streaming) - << "Future interface doesn't support streaming. " - << "client_streaming=" << client_streaming << ", " - << "server_streaming=" << server_streaming; - p->Print(vars, - "$ListenableFuture$<$output_type$> $lower_method_name$(\n" - " $input_type$ request)"); - break; - } - - if (interface) { - p->Print(";\n"); - continue; - } - // Method body. - p->Print(" {\n"); - p->Indent(); - if (impl_base) { - switch (call_type) { - // NB: Skipping validation of service methods. If something is wrong, - // we wouldn't get to this point as compiler would return errors when - // generating service interface. - case ASYNC_CALL: - if (client_streaming) { - p->Print(vars, - "return " - "asyncUnimplementedStreamingCall($method_method_name$(), " - "responseObserver);\n"); - } else { - p->Print(vars, - "asyncUnimplementedUnaryCall($method_method_name$(), " - "responseObserver);\n"); - } - break; - default: - break; - } - } else if (!interface) { - switch (call_type) { - case BLOCKING_CALL: - GRPC_CODEGEN_CHECK(!client_streaming) - << "Blocking client streaming interface is not available"; - if (server_streaming) { - vars["calls_method"] = "blockingServerStreamingCall"; - vars["params"] = "request"; - } else { - vars["calls_method"] = "blockingUnaryCall"; - vars["params"] = "request"; - } - p->Print(vars, - "return $calls_method$(\n" - " getChannel(), $method_method_name$(), " - "getCallOptions(), $params$);\n"); - break; - case ASYNC_CALL: - if (server_streaming) { - if (client_streaming) { - vars["calls_method"] = "asyncBidiStreamingCall"; - vars["params"] = "responseObserver"; - } else { - vars["calls_method"] = "asyncServerStreamingCall"; - vars["params"] = "request, responseObserver"; - } - } else { - if (client_streaming) { - vars["calls_method"] = "asyncClientStreamingCall"; - vars["params"] = "responseObserver"; - } else { - vars["calls_method"] = "asyncUnaryCall"; - vars["params"] = "request, responseObserver"; - } - } - vars["last_line_prefix"] = client_streaming ? "return " : ""; - p->Print(vars, - "$last_line_prefix$$calls_method$(\n" - " getChannel().newCall($method_method_name$(), " - "getCallOptions()), $params$);\n"); - break; - case FUTURE_CALL: - GRPC_CODEGEN_CHECK(!client_streaming && !server_streaming) - << "Future interface doesn't support streaming. " - << "client_streaming=" << client_streaming << ", " - << "server_streaming=" << server_streaming; - vars["calls_method"] = "futureUnaryCall"; - p->Print(vars, - "return $calls_method$(\n" - " getChannel().newCall($method_method_name$(), " - "getCallOptions()), request);\n"); - break; - } - } - p->Outdent(); - p->Print("}\n"); - } - - if (impl_base) { - p->Print("\n"); - p->Print( - vars, - "@$Override$ public final $ServerServiceDefinition$ bindService() {\n"); - vars["instance"] = "this"; - PrintBindServiceMethodBody(p, vars, service); - p->Print("}\n"); - } - - p->Outdent(); - p->Print("}\n\n"); -} - -static bool CompareMethodClientStreaming( - 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) { - // 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()); - for (int i = 0; i < service->method_count(); ++i) { - sorted_methods[i] = service->method(i); - } - stable_sort(sorted_methods.begin(), sorted_methods.end(), - CompareMethodClientStreaming); - for (size_t i = 0; i < sorted_methods.size(); i++) { - auto& method = sorted_methods[i]; - vars["method_id"] = to_string(i); - vars["method_id_name"] = MethodIdFieldName(&*method); - p->Print(vars, - "private static final int $method_id_name$ = $method_id$;\n"); - } - p->Print("\n"); - vars["service_name"] = service->name() + "ImplBase"; - p->Print(vars, - "private static final class MethodHandlers<Req, Resp> implements\n" - " io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,\n" - " io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,\n" - " io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,\n" - " io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {\n" - " private final $service_name$ serviceImpl;\n" - " private final int methodId;\n" - "\n" - " MethodHandlers($service_name$ serviceImpl, int methodId) {\n" - " this.serviceImpl = serviceImpl;\n" - " this.methodId = methodId;\n" - " }\n\n"); - p->Indent(); - p->Print(vars, - "@$Override$\n" - "@java.lang.SuppressWarnings(\"unchecked\")\n" - "public void invoke(Req request, $StreamObserver$<Resp> " - "responseObserver) {\n" - " switch (methodId) {\n"); - p->Indent(); - p->Indent(); - - for (int i = 0; i < service->method_count(); ++i) { - auto method = service->method(i); - 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()); - vars["output_type"] = JavaClassName(vars, method->get_output_type_name()); - p->Print(vars, - "case $method_id_name$:\n" - " serviceImpl.$lower_method_name$(($input_type$) request,\n" - " ($StreamObserver$<$output_type$>) responseObserver);\n" - " break;\n"); - } - p->Print( - "default:\n" - " throw new AssertionError();\n"); - - p->Outdent(); - p->Outdent(); - p->Print( - " }\n" - "}\n\n"); - - p->Print(vars, - "@$Override$\n" - "@java.lang.SuppressWarnings(\"unchecked\")\n" - "public $StreamObserver$<Req> invoke(\n" - " $StreamObserver$<Resp> responseObserver) {\n" - " switch (methodId) {\n"); - p->Indent(); - p->Indent(); - - for (int i = 0; i < service->method_count(); ++i) { - auto method = service->method(i); - 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()); - vars["output_type"] = JavaClassName(vars, method->get_output_type_name()); - p->Print( - vars, - "case $method_id_name$:\n" - " return ($StreamObserver$<Req>) serviceImpl.$lower_method_name$(\n" - " ($StreamObserver$<$output_type$>) responseObserver);\n"); - } - p->Print( - "default:\n" - " throw new AssertionError();\n"); - - p->Outdent(); - p->Outdent(); - p->Print( - " }\n" - "}\n"); - - p->Outdent(); - p->Print("}\n\n"); -} - -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"] = - // service->name() + "FileDescriptorSupplier"; - // vars["proto_method_descriptor_supplier"] = service->name() + - // "MethodDescriptorSupplier"; vars["proto_class_name"] = - // google::protobuf::compiler::java::ClassName(service->file()); - // p->Print( - // vars, - // "private static abstract class - // $proto_base_descriptor_supplier$\n" " implements - // $ProtoFileDescriptorSupplier$, - // $ProtoServiceDescriptorSupplier$ {\n" " - // $proto_base_descriptor_supplier$() {}\n" - // "\n" - // " @$Override$\n" - // " public com.google.protobuf.Descriptors.FileDescriptor - // getFileDescriptor() {\n" " return - // $proto_class_name$.getDescriptor();\n" " }\n" - // "\n" - // " @$Override$\n" - // " public com.google.protobuf.Descriptors.ServiceDescriptor - // getServiceDescriptor() {\n" " return - // getFileDescriptor().findServiceByName(\"$service_name$\");\n" - // " }\n" - // "}\n" - // "\n" - // "private static final class - // $proto_file_descriptor_supplier$\n" " extends - // $proto_base_descriptor_supplier$ {\n" " - // $proto_file_descriptor_supplier$() {}\n" - // "}\n" - // "\n" - // "private static final class - // $proto_method_descriptor_supplier$\n" " extends - // $proto_base_descriptor_supplier$\n" " implements - // $ProtoMethodDescriptorSupplier$ {\n" " private final - // String methodName;\n" - // "\n" - // " $proto_method_descriptor_supplier$(String methodName) - // {\n" " this.methodName = methodName;\n" " }\n" - // "\n" - // " @$Override$\n" - // " public com.google.protobuf.Descriptors.MethodDescriptor - // getMethodDescriptor() {\n" " return - // getServiceDescriptor().findMethodByName(methodName);\n" " - // }\n" - // "}\n\n"); - - p->Print( - vars, - "private static volatile $ServiceDescriptor$ serviceDescriptor;\n\n"); - - p->Print(vars, - "public static $ServiceDescriptor$ getServiceDescriptor() {\n"); - p->Indent(); - p->Print(vars, "$ServiceDescriptor$ result = serviceDescriptor;\n"); - p->Print("if (result == null) {\n"); - p->Indent(); - p->Print(vars, "synchronized ($service_class_name$.class) {\n"); - p->Indent(); - p->Print("result = serviceDescriptor;\n"); - p->Print("if (result == null) {\n"); - p->Indent(); - - p->Print(vars, - "serviceDescriptor = result = " - "$ServiceDescriptor$.newBuilder(SERVICE_NAME)"); - p->Indent(); - p->Indent(); - p->Print(vars, "\n.setSchemaDescriptor(null)"); - for (int i = 0; i < service->method_count(); ++i) { - auto method = service->method(i); - vars["method_method_name"] = MethodPropertiesGetterName(&*method); - p->Print(vars, "\n.addMethod($method_method_name$())"); - } - p->Print("\n.build();\n"); - p->Outdent(); - p->Outdent(); - - p->Outdent(); - p->Print("}\n"); - p->Outdent(); - p->Print("}\n"); - p->Outdent(); - p->Print("}\n"); - p->Print("return result;\n"); - p->Outdent(); - p->Print("}\n"); -} - -static void PrintBindServiceMethodBody(Printer* p, VARS& vars, - const ServiceDescriptor* service) { - vars["service_name"] = service->name(); - p->Indent(); - p->Print(vars, - "return " - "$ServerServiceDefinition$.builder(getServiceDescriptor())\n"); - p->Indent(); - p->Indent(); - for (int i = 0; i < service->method_count(); ++i) { - auto method = service->method(i); - vars["lower_method_name"] = LowerMethodName(&*method); - vars["method_method_name"] = MethodPropertiesGetterName(&*method); - 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(); - if (client_streaming) { - if (server_streaming) { - vars["calls_method"] = "asyncBidiStreamingCall"; - } else { - vars["calls_method"] = "asyncClientStreamingCall"; - } - } else { - if (server_streaming) { - vars["calls_method"] = "asyncServerStreamingCall"; - } else { - vars["calls_method"] = "asyncUnaryCall"; - } - } - p->Print(vars, ".addMethod(\n"); - p->Indent(); - p->Print(vars, - "$method_method_name$(),\n" - "$calls_method$(\n"); - p->Indent(); - p->Print(vars, - "new MethodHandlers<\n" - " $input_type$,\n" - " $output_type$>(\n" - " $instance$, $method_id_name$)))\n"); - p->Outdent(); - p->Outdent(); - } - p->Print(".build();\n"); - p->Outdent(); - p->Outdent(); - p->Outdent(); -} - -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()); - vars["grpc_version"] = ""; -#ifdef GRPC_VERSION - if (!disable_version) { - vars["grpc_version"] = " (version " XSTR(GRPC_VERSION) ")"; - } -#else - (void)disable_version; -#endif - // TODO(nmittler): Replace with WriteServiceDocComment once included by - // protobuf distro. - GrpcWriteServiceDocComment(p, vars, service); - p->Print(vars, - "@$Generated$(\n" - " value = \"by gRPC proto compiler$grpc_version$\",\n" - " comments = \"Source: $file_name$.fbs\")\n" - "public final class $service_class_name$ {\n\n"); - p->Indent(); - p->Print(vars, "private $service_class_name$() {}\n\n"); - - p->Print(vars, - "public static final String SERVICE_NAME = " - "\"$Package$$service_name$\";\n\n"); - - PrintMethodFields(p, vars, service); - - // TODO(nmittler): Replace with WriteDocComment once included by protobuf - // distro. - GrpcWriteDocComment( - p, vars, - " Creates a new async stub that supports all call types for the service"); - p->Print(vars, - "public static $service_name$Stub newStub($Channel$ channel) {\n"); - p->Indent(); - p->Print(vars, "return new $service_name$Stub(channel);\n"); - p->Outdent(); - p->Print("}\n\n"); - - // TODO(nmittler): Replace with WriteDocComment once included by protobuf - // distro. - GrpcWriteDocComment( - p, vars, - " Creates a new blocking-style stub that supports unary and streaming " - "output calls on the service"); - p->Print(vars, - "public static $service_name$BlockingStub newBlockingStub(\n" - " $Channel$ channel) {\n"); - p->Indent(); - p->Print(vars, "return new $service_name$BlockingStub(channel);\n"); - p->Outdent(); - p->Print("}\n\n"); - - // TODO(nmittler): Replace with WriteDocComment once included by protobuf - // distro. - GrpcWriteDocComment( - p, vars, - " Creates a new ListenableFuture-style stub that supports unary calls " - "on the service"); - p->Print(vars, - "public static $service_name$FutureStub newFutureStub(\n" - " $Channel$ channel) {\n"); - p->Indent(); - p->Print(vars, "return new $service_name$FutureStub(channel);\n"); - p->Outdent(); - p->Print("}\n\n"); - - PrintStub(p, vars, service, ABSTRACT_CLASS); - PrintStub(p, vars, service, ASYNC_CLIENT_IMPL); - PrintStub(p, vars, service, BLOCKING_CLIENT_IMPL); - PrintStub(p, vars, service, FUTURE_CLIENT_IMPL); - - PrintMethodHandlerClass(p, vars, service); - PrintGetServiceDescriptorMethod(p, vars, service); - p->Outdent(); - p->Print("}\n"); -} - -void PrintStaticImports(Printer* p) { - p->Print( - "import java.nio.ByteBuffer;\n" - "import static " - "io.grpc.MethodDescriptor.generateFullMethodName;\n" - "import static " - "io.grpc.stub.ClientCalls.asyncBidiStreamingCall;\n" - "import static " - "io.grpc.stub.ClientCalls.asyncClientStreamingCall;\n" - "import static " - "io.grpc.stub.ClientCalls.asyncServerStreamingCall;\n" - "import static " - "io.grpc.stub.ClientCalls.asyncUnaryCall;\n" - "import static " - "io.grpc.stub.ClientCalls.blockingServerStreamingCall;\n" - "import static " - "io.grpc.stub.ClientCalls.blockingUnaryCall;\n" - "import static " - "io.grpc.stub.ClientCalls.futureUnaryCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncServerStreamingCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncUnaryCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n\n"); -} - -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. - vars["String"] = "java.lang.String"; - vars["Deprecated"] = "java.lang.Deprecated"; - vars["Override"] = "java.lang.Override"; - vars["Channel"] = "io.grpc.Channel"; - vars["CallOptions"] = "io.grpc.CallOptions"; - vars["MethodType"] = "io.grpc.MethodDescriptor.MethodType"; - vars["ServerMethodDefinition"] = "io.grpc.ServerMethodDefinition"; - vars["BindableService"] = "io.grpc.BindableService"; - vars["ServerServiceDefinition"] = "io.grpc.ServerServiceDefinition"; - vars["ServiceDescriptor"] = "io.grpc.ServiceDescriptor"; - vars["ProtoFileDescriptorSupplier"] = - "io.grpc.protobuf.ProtoFileDescriptorSupplier"; - vars["ProtoServiceDescriptorSupplier"] = - "io.grpc.protobuf.ProtoServiceDescriptorSupplier"; - vars["ProtoMethodDescriptorSupplier"] = - "io.grpc.protobuf.ProtoMethodDescriptorSupplier"; - vars["AbstractStub"] = "io.grpc.stub.AbstractStub"; - vars["MethodDescriptor"] = "io.grpc.MethodDescriptor"; - vars["NanoUtils"] = "io.grpc.protobuf.nano.NanoUtils"; - vars["StreamObserver"] = "io.grpc.stub.StreamObserver"; - vars["Iterator"] = "java.util.Iterator"; - vars["Generated"] = "javax.annotation.Generated"; - vars["ListenableFuture"] = - "com.google.common.util.concurrent.ListenableFuture"; - vars["ExperimentalApi"] = "io.grpc.ExperimentalApi"; - - PrintStaticImports(printer); - - PrintService(printer, vars, service, disable_version); -} - -grpc::string GenerateServiceSource( - grpc_generator::File* file, const grpc_generator::Service* service, - grpc_java_generator::Parameters* parameters) { - grpc::string out; - auto printer = file->CreatePrinter(&out); - VARS vars; - vars["flatc_version"] = grpc::string( - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "." FLATBUFFERS_STRING( - FLATBUFFERS_VERSION_MINOR) "." FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION)); - - vars["file_name"] = file->filename(); - - if (!parameters->package_name.empty()) { - vars["Package"] = parameters->package_name; // ServiceJavaPackage(service); - } - GenerateImports(file, &*printer, vars); - GenerateService(service, &*printer, vars, false); - return out; -} - -} // namespace grpc_java_generator diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/java_generator.h b/contrib/libs/flatbuffers/grpc/src/compiler/java_generator.h deleted file mode 100644 index b101fbf565..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/java_generator.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2016 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NET_GRPC_COMPILER_JAVA_GENERATOR_H_ -#define NET_GRPC_COMPILER_JAVA_GENERATOR_H_ - -#include <stdlib.h> // for abort() -#include <iostream> -#include <map> -#include <string> - -#include "src/compiler/schema_interface.h" - -class LogMessageVoidify { - public: - LogMessageVoidify() {} - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(std::ostream&) {} -}; - -class LogHelper { - std::ostream* os_; - - public: - LogHelper(std::ostream* os) : os_(os) {} -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning( \ - disable : 4722) // the flow of control terminates in a destructor - // (needed to compile ~LogHelper where destructor emits abort intentionally - - // inherited from grpc/java code generator). -#endif - ~LogHelper() { - *os_ << std::endl; - ::abort(); - } -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - std::ostream& get_os() const { return *os_; } -}; - -// Abort the program after logging the mesage if the given condition is not -// true. Otherwise, do nothing. -#define GRPC_CODEGEN_CHECK(x) \ - (x) ? (void)0 \ - : LogMessageVoidify() & LogHelper(&std::cerr).get_os() \ - << "CHECK FAILED: " << __FILE__ << ":" \ - << __LINE__ << ": " - -// Abort the program after logging the mesage. -#define GRPC_CODEGEN_FAIL GRPC_CODEGEN_CHECK(false) - -namespace grpc_java_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 grpc::string custom_method_io_type; - - // Package name for the service - grpc::string package_name; -}; - -// Return the source of the generated service file. -grpc::string GenerateServiceSource(grpc_generator::File* file, - const grpc_generator::Service* service, - grpc_java_generator::Parameters* parameters); - -} // namespace grpc_java_generator - -#endif // NET_GRPC_COMPILER_JAVA_GENERATOR_H_ diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/python_generator.cc b/contrib/libs/flatbuffers/grpc/src/compiler/python_generator.cc deleted file mode 100644 index 8108db45d5..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/python_generator.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include <map> -#include <sstream> - -#include "flatbuffers/util.h" -#include "src/compiler/python_generator.h" - -namespace grpc_python_generator { - -grpc::string GenerateMethodType(const grpc_generator::Method *method) { - - if (method->NoStreaming()) - return "unary_unary"; - - if (method->ServerStreaming()) - return "unary_stream"; - - if (method->ClientStreaming()) - return "stream_unary"; - - return "stream_stream"; -} - -grpc::string GenerateMethodInput(const grpc_generator::Method *method) { - - if (method->NoStreaming() || method->ServerStreaming()) - return "self, request, context"; - - return "self, request_iterator, context"; -} - -void GenerateStub(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, "class $ServiceName$Stub(object):\n"); - printer->Indent(); - printer->Print("\"\"\" Interface exported by the server. \"\"\""); - printer->Print("\n\n"); - printer->Print("def __init__(self, channel):\n"); - printer->Indent(); - printer->Print("\"\"\" Constructor. \n\n"); - printer->Print("Args: \n"); - printer->Print("channel: A grpc.Channel. \n"); - printer->Print("\"\"\"\n\n"); - - for (int j = 0; j < service->method_count(); j++) { - auto method = service->method(j); - vars["MethodName"] = method->name(); - vars["MethodType"] = GenerateMethodType(&*method); - printer->Print(vars, "self.$MethodName$ = channel.$MethodType$(\n"); - printer->Indent(); - printer->Print(vars, "\"/$PATH$$ServiceName$/$MethodName$\"\n"); - printer->Print(")\n"); - printer->Outdent(); - printer->Print("\n"); - } - printer->Outdent(); - printer->Outdent(); - printer->Print("\n"); -} - -void GenerateServicer(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, "class $ServiceName$Servicer(object):\n"); - printer->Indent(); - printer->Print("\"\"\" Interface exported by the server. \"\"\""); - printer->Print("\n\n"); - - for (int j = 0; j < service->method_count(); j++) { - auto method = service->method(j); - vars["MethodName"] = method->name(); - vars["MethodInput"] = GenerateMethodInput(&*method); - printer->Print(vars, "def $MethodName$($MethodInput$):\n"); - printer->Indent(); - printer->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n"); - printer->Print("context.set_details('Method not implemented!')\n"); - printer->Print("raise NotImplementedError('Method not implemented!')\n"); - printer->Outdent(); - printer->Print("\n\n"); - } - printer->Outdent(); - printer->Print("\n"); - -} - -void GenerateRegister(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, "def add_$ServiceName$Servicer_to_server(servicer, server):\n"); - printer->Indent(); - printer->Print("rpc_method_handlers = {\n"); - printer->Indent(); - for (int j = 0; j < service->method_count(); j++) { - auto method = service->method(j); - vars["MethodName"] = method->name(); - vars["MethodType"] = GenerateMethodType(&*method); - printer->Print(vars, "'$MethodName$': grpc.$MethodType$_rpc_method_handler(\n"); - printer->Indent(); - printer->Print(vars, "servicer.$MethodName$\n"); - printer->Outdent(); - printer->Print("),\n"); - } - printer->Outdent(); - printer->Print("}\n"); - printer->Print(vars, "generic_handler = grpc.method_handlers_generic_handler(\n"); - printer->Indent(); - printer->Print(vars, "'$PATH$$ServiceName$', rpc_method_handlers)\n"); - printer->Outdent(); - printer->Print("server.add_generic_rpc_handlers((generic_handler,))"); - printer->Outdent(); - printer->Print("\n"); -} - -grpc::string Generate(grpc_generator::File *file, - const grpc_generator::Service *service) { - grpc::string output; - std::map<grpc::string, grpc::string> vars; - vars["PATH"] = file->package(); - if (!file->package().empty()) { vars["PATH"].append("."); } - vars["ServiceName"] = service->name(); - auto printer = file->CreatePrinter(&output); - GenerateStub(service, &*printer, &vars); - GenerateServicer(service, &*printer, &vars); - GenerateRegister(service, &*printer, &vars); - return output; -} - -} // namespace grpc_python_generator diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/python_generator.h b/contrib/libs/flatbuffers/grpc/src/compiler/python_generator.h deleted file mode 100644 index 4f8f5cc806..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/python_generator.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H -#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H - -#include <utility> - -#include "src/compiler/config.h" -#include "src/compiler/schema_interface.h" - -namespace grpc_python_generator { - -grpc::string Generate(grpc_generator::File *file, - const grpc_generator::Service *service); -} // namespace grpc_python_generator - -#endif // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/schema_interface.h b/contrib/libs/flatbuffers/grpc/src/compiler/schema_interface.h deleted file mode 100644 index 0449498198..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/schema_interface.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H -#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H - -#include <memory> -#include <vector> - -#include "src/compiler/config.h" - -#ifndef GRPC_CUSTOM_STRING -# include <string> -# define GRPC_CUSTOM_STRING std::string -#endif - -namespace grpc { - -typedef GRPC_CUSTOM_STRING string; - -} // namespace grpc - -namespace grpc_generator { - -// A common interface for objects having comments in the source. -// Return formatted comments to be inserted in generated code. -struct CommentHolder { - virtual ~CommentHolder() {} - virtual grpc::string GetLeadingComments(const grpc::string prefix) const = 0; - virtual grpc::string GetTrailingComments(const grpc::string prefix) const = 0; - virtual std::vector<grpc::string> GetAllComments() const = 0; -}; - -// An abstract interface representing a method. -struct Method : public CommentHolder { - virtual ~Method() {} - - virtual grpc::string name() const = 0; - - virtual grpc::string input_type_name() const = 0; - virtual grpc::string output_type_name() const = 0; - - virtual bool get_module_and_message_path_input( - grpc::string *str, grpc::string generator_file_name, - bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0; - virtual bool get_module_and_message_path_output( - grpc::string *str, grpc::string generator_file_name, - bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0; - - virtual std::vector<grpc::string> get_input_namespace_parts() const = 0; - virtual grpc::string get_input_type_name() const = 0; - virtual std::vector<grpc::string> get_output_namespace_parts() const = 0; - virtual grpc::string get_output_type_name() const = 0; - - virtual grpc::string get_fb_builder() const = 0; - - virtual bool NoStreaming() const = 0; - virtual bool ClientStreaming() const = 0; - virtual bool ServerStreaming() const = 0; - virtual bool BidiStreaming() const = 0; -}; - -// An abstract interface representing a service. -struct Service : public CommentHolder { - virtual ~Service() {} - - virtual std::vector<grpc::string> namespace_parts() const = 0; - virtual grpc::string name() const = 0; - virtual bool is_internal() const = 0; - - virtual int method_count() const = 0; - virtual std::unique_ptr<const Method> method(int i) const = 0; -}; - -struct Printer { - virtual ~Printer() {} - - virtual void Print(const std::map<grpc::string, grpc::string> &vars, - const char *template_string) = 0; - virtual void Print(const char *string) = 0; - virtual void SetIndentationSize(const int size) = 0; - virtual void Indent() = 0; - virtual void Outdent() = 0; -}; - -// An interface that allows the source generated to be output using various -// libraries/idls/serializers. -struct File : public CommentHolder { - virtual ~File() {} - - virtual grpc::string filename() const = 0; - virtual grpc::string filename_without_ext() const = 0; - virtual grpc::string package() const = 0; - virtual std::vector<grpc::string> package_parts() const = 0; - virtual grpc::string additional_headers() const = 0; - - virtual int service_count() const = 0; - virtual std::unique_ptr<const Service> service(int i) const = 0; - - virtual std::unique_ptr<Printer> CreatePrinter( - grpc::string *str, const char indentation_type = ' ') const = 0; -}; -} // namespace grpc_generator - -#endif // GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/swift_generator.cc b/contrib/libs/flatbuffers/grpc/src/compiler/swift_generator.cc deleted file mode 100644 index 403a803ef1..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/swift_generator.cc +++ /dev/null @@ -1,438 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/* - * NOTE: The following implementation is a translation for the Swift-grpc - * generator since flatbuffers doesnt allow plugins for now. if an issue arises - * please open an issue in the flatbuffers repository. This file should always - * be maintained according to the Swift-grpc repository - */ -#include <map> -#include <sstream> - -#include "flatbuffers/util.h" -#include "src/compiler/schema_interface.h" -#include "src/compiler/swift_generator.h" - -namespace grpc_swift_generator { - -std::string WrapInNameSpace(const std::vector<std::string> &components, - const grpc::string &name) { - std::string qualified_name; - for (auto it = components.begin(); it != components.end(); ++it) - qualified_name += *it + "_"; - return qualified_name + name; -} - -grpc::string GenerateMessage(const std::vector<std::string> &components, - const grpc::string &name) { - return "Message<" + WrapInNameSpace(components, name) + ">"; -} - -// MARK: - Client - -void GenerateClientFuncName(const grpc_generator::Method *method, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - if (method->NoStreaming()) { - printer->Print(vars, - " $GenAccess$func $MethodName$(\n" - " _ request: $Input$\n" - " , callOptions: CallOptions?$isNil$\n" - " ) -> UnaryCall<$Input$, $Output$>"); - return; - } - - if (method->ServerStreaming()) { - printer->Print(vars, - " $GenAccess$func $MethodName$(\n" - " _ request: $Input$\n" - " , callOptions: CallOptions?$isNil$,\n" - " handler: @escaping ($Output$) -> Void\n" - " ) -> ServerStreamingCall<$Input$, $Output$>"); - return; - } - - if (method->ClientStreaming()) { - printer->Print(vars, - " $GenAccess$func $MethodName$(\n" - " callOptions: CallOptions?$isNil$\n" - " ) -> ClientStreamingCall<$Input$, $Output$>"); - return; - } - - printer->Print(vars, - " $GenAccess$func $MethodName$(\n" - " callOptions: CallOptions?$isNil$,\n" - " handler: @escaping ($Output$ ) -> Void\n" - " ) -> BidirectionalStreamingCall<$Input$, $Output$>"); -} - -void GenerateClientFuncBody(const grpc_generator::Method *method, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - vars["Interceptor"] = - "interceptors: self.interceptors?.make$MethodName$Interceptors() ?? []"; - if (method->NoStreaming()) { - printer->Print( - vars, - " return self.makeUnaryCall(\n" - " path: \"/$PATH$$ServiceName$/$MethodName$\",\n" - " request: request,\n" - " callOptions: callOptions ?? self.defaultCallOptions,\n" - " $Interceptor$\n" - " )\n"); - return; - } - - if (method->ServerStreaming()) { - printer->Print( - vars, - " return self.makeServerStreamingCall(\n" - " path: \"/$PATH$$ServiceName$/$MethodName$\",\n" - " request: request,\n" - " callOptions: callOptions ?? self.defaultCallOptions,\n" - " $Interceptor$,\n" - " handler: handler\n" - " )\n"); - return; - } - - if (method->ClientStreaming()) { - printer->Print( - vars, - " return self.makeClientStreamingCall(\n" - " path: \"/$PATH$$ServiceName$/$MethodName$\",\n" - " callOptions: callOptions ?? self.defaultCallOptions,\n" - " $Interceptor$\n" - " )\n"); - return; - } - printer->Print(vars, - " return self.makeBidirectionalStreamingCall(\n" - " path: \"/$PATH$$ServiceName$/$MethodName$\",\n" - " callOptions: callOptions ?? self.defaultCallOptions,\n" - " $Interceptor$,\n" - " handler: handler\n" - " )\n"); -} - -void GenerateClientProtocol(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print( - vars, - "$ACCESS$ protocol $ServiceQualifiedName$ClientProtocol: GRPCClient {"); - printer->Print("\n\n"); - printer->Print(" var serviceName: String { get }"); - printer->Print("\n\n"); - printer->Print( - vars, - " var interceptors: " - "$ServiceQualifiedName$ClientInterceptorFactoryProtocol? { get }"); - printer->Print("\n\n"); - - vars["GenAccess"] = ""; - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - vars["isNil"] = ""; - GenerateClientFuncName(method.get(), &*printer, &vars); - printer->Print("\n\n"); - } - printer->Print("}\n\n"); - - printer->Print(vars, "extension $ServiceQualifiedName$ClientProtocol {"); - printer->Print("\n\n"); - printer->Print(vars, - " $ACCESS$ var serviceName: String { " - "\"$PATH$$ServiceName$\" }\n"); - - vars["GenAccess"] = service->is_internal() ? "internal " : "public "; - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - vars["isNil"] = " = nil"; - printer->Print("\n"); - GenerateClientFuncName(method.get(), &*printer, &vars); - printer->Print(" {\n"); - GenerateClientFuncBody(method.get(), &*printer, &vars); - printer->Print(" }\n"); - } - printer->Print("}\n\n"); - - printer->Print(vars, - "$ACCESS$ protocol " - "$ServiceQualifiedName$ClientInterceptorFactoryProtocol {\n"); - - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - printer->Print( - vars, - " /// - Returns: Interceptors to use when invoking '$MethodName$'.\n"); - printer->Print(vars, - " func make$MethodName$Interceptors() -> " - "[ClientInterceptor<$Input$, $Output$>]\n\n"); - } - printer->Print("}\n\n"); -} - -void GenerateClientClass(grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, - "$ACCESS$ final class $ServiceQualifiedName$ServiceClient: " - "$ServiceQualifiedName$ClientProtocol {\n"); - printer->Print(vars, " $ACCESS$ let channel: GRPCChannel\n"); - printer->Print(vars, " $ACCESS$ var defaultCallOptions: CallOptions\n"); - printer->Print(vars, - " $ACCESS$ var interceptors: " - "$ServiceQualifiedName$ClientInterceptorFactoryProtocol?\n"); - printer->Print("\n"); - printer->Print( - vars, - " $ACCESS$ init(\n" - " channel: GRPCChannel,\n" - " defaultCallOptions: CallOptions = CallOptions(),\n" - " interceptors: " - "$ServiceQualifiedName$ClientInterceptorFactoryProtocol? = nil\n" - " ) {\n"); - printer->Print(" self.channel = channel\n"); - printer->Print(" self.defaultCallOptions = defaultCallOptions\n"); - printer->Print(" self.interceptors = interceptors\n"); - printer->Print(" }"); - printer->Print("\n"); - printer->Print("}\n"); -} - -// MARK: - Server - -grpc::string GenerateServerFuncName(const grpc_generator::Method *method) { - if (method->NoStreaming()) { - return "func $MethodName$(request: $Input$" - ", context: StatusOnlyCallContext) -> EventLoopFuture<$Output$>"; - } - - if (method->ClientStreaming()) { - return "func $MethodName$(context: UnaryResponseCallContext<$Output$>) -> " - "EventLoopFuture<(StreamEvent<$Input$" - ">) -> Void>"; - } - - if (method->ServerStreaming()) { - return "func $MethodName$(request: $Input$" - ", context: StreamingResponseCallContext<$Output$>) -> " - "EventLoopFuture<GRPCStatus>"; - } - return "func $MethodName$(context: StreamingResponseCallContext<$Output$>) " - "-> EventLoopFuture<(StreamEvent<$Input$>) -> Void>"; -} - -grpc::string GenerateServerExtensionBody(const grpc_generator::Method *method) { - grpc::string start = " case \"$MethodName$\":\n "; - grpc::string interceptors = - " interceptors: self.interceptors?.make$MethodName$Interceptors() " - "?? [],\n"; - if (method->NoStreaming()) { - return start + - "return UnaryServerHandler(\n" - " context: context,\n" - " requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n" - " responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" + - interceptors + - " userFunction: self.$MethodName$(request:context:))\n"; - } - if (method->ServerStreaming()) { - return start + - "return ServerStreamingServerHandler(\n" - " context: context,\n" - " requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n" - " responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" + - interceptors + - " userFunction: self.$MethodName$(request:context:))\n"; - } - if (method->ClientStreaming()) { - return start + - "return ClientStreamingServerHandler(\n" - " context: context,\n" - " requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n" - " responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" + - interceptors + - " observerFactory: self.$MethodName$(context:))\n"; - } - if (method->BidiStreaming()) { - return start + - "return BidirectionalStreamingServerHandler(\n" - " context: context,\n" - " requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n" - " responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" + - interceptors + - " observerFactory: self.$MethodName$(context:))\n"; - } - return ""; -} - -void GenerateServerProtocol(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, - "$ACCESS$ protocol $ServiceQualifiedName$Provider: " - "CallHandlerProvider {\n"); - printer->Print( - vars, - " var interceptors: " - "$ServiceQualifiedName$ServerInterceptorFactoryProtocol? { get }\n"); - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - printer->Print(" "); - auto func = GenerateServerFuncName(method.get()); - printer->Print(vars, func.c_str()); - printer->Print("\n"); - } - printer->Print("}\n\n"); - - printer->Print(vars, "$ACCESS$ extension $ServiceQualifiedName$Provider {\n"); - printer->Print("\n"); - printer->Print(vars, - " var serviceName: Substring { return " - "\"$PATH$$ServiceName$\" }\n"); - printer->Print("\n"); - printer->Print( - " func handle(method name: Substring, context: " - "CallHandlerContext) -> GRPCServerHandlerProtocol? {\n"); - printer->Print(" switch name {\n"); - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - auto body = GenerateServerExtensionBody(method.get()); - printer->Print(vars, body.c_str()); - printer->Print("\n"); - } - printer->Print(" default: return nil;\n"); - printer->Print(" }\n"); - printer->Print(" }\n\n"); - printer->Print("}\n\n"); - - printer->Print(vars, - "$ACCESS$ protocol " - "$ServiceQualifiedName$ServerInterceptorFactoryProtocol {\n"); - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - printer->Print( - vars, - " /// - Returns: Interceptors to use when handling '$MethodName$'.\n" - " /// Defaults to calling `self.makeInterceptors()`.\n"); - printer->Print(vars, - " func make$MethodName$Interceptors() -> " - "[ServerInterceptor<$Input$, $Output$>]\n\n"); - } - printer->Print("}"); -} - -grpc::string Generate(grpc_generator::File *file, - const grpc_generator::Service *service) { - grpc::string output; - std::map<grpc::string, grpc::string> vars; - vars["PATH"] = file->package(); - if (!file->package().empty()) { vars["PATH"].append("."); } - vars["ServiceQualifiedName"] = - WrapInNameSpace(service->namespace_parts(), service->name()); - vars["ServiceName"] = service->name(); - vars["ACCESS"] = service->is_internal() ? "internal" : "public"; - auto printer = file->CreatePrinter(&output); - printer->Print( - vars, - "/// Usage: instantiate $ServiceQualifiedName$ServiceClient, then call " - "methods of this protocol to make API calls.\n"); - GenerateClientProtocol(service, &*printer, &vars); - GenerateClientClass(&*printer, &vars); - printer->Print("\n"); - GenerateServerProtocol(service, &*printer, &vars); - return output; -} - -grpc::string GenerateHeader() { - grpc::string code; - code += - "/// The following code is generated by the Flatbuffers library which " - "might not be in sync with grpc-swift\n"; - code += - "/// in case of an issue please open github issue, though it would be " - "maintained\n"; - code += "\n"; - code += "// swiftlint:disable all\n"; - code += "// swiftformat:disable all\n"; - code += "\n"; - code += "import Foundation\n"; - code += "import GRPC\n"; - code += "import NIO\n"; - code += "import NIOHTTP1\n"; - code += "import FlatBuffers\n"; - code += "\n"; - code += - "public protocol GRPCFlatBufPayload: GRPCPayload, FlatBufferGRPCMessage " - "{}\n"; - - code += "public extension GRPCFlatBufPayload {\n"; - code += " init(serializedByteBuffer: inout NIO.ByteBuffer) throws {\n"; - code += - " self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: " - "serializedByteBuffer.readableBytesView, count: " - "serializedByteBuffer.readableBytes))\n"; - code += " }\n"; - - code += " func serialize(into buffer: inout NIO.ByteBuffer) throws {\n"; - code += - " let buf = UnsafeRawBufferPointer(start: self.rawPointer, count: " - "Int(self.size))\n"; - code += " buffer.writeBytes(buf)\n"; - code += " }\n"; - code += "}\n"; - code += "extension Message: GRPCFlatBufPayload {}\n"; - return code; -} -} // namespace grpc_swift_generator diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/swift_generator.h b/contrib/libs/flatbuffers/grpc/src/compiler/swift_generator.h deleted file mode 100644 index 1639cb07c8..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/swift_generator.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * 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 "src/compiler/config.h" -#include "src/compiler/schema_interface.h" - -#ifndef GRPC_CUSTOM_STRING -# include <string> -# define GRPC_CUSTOM_STRING std::string -#endif - -namespace grpc { - -typedef GRPC_CUSTOM_STRING string; - -} // namespace grpc - -namespace grpc_swift_generator { -grpc::string Generate(grpc_generator::File *file, - const grpc_generator::Service *service); -grpc::string GenerateHeader(); -} // namespace grpc_swift_generator diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/ts_generator.cc b/contrib/libs/flatbuffers/grpc/src/compiler/ts_generator.cc deleted file mode 100644 index e49fd8d925..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/ts_generator.cc +++ /dev/null @@ -1,523 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/* - * NOTE: The following implementation is a translation for the Swift-grpc - * generator since flatbuffers doesnt allow plugins for now. if an issue arises - * please open an issue in the flatbuffers repository. This file should always - * be maintained according to the Swift-grpc repository - */ - -#include <map> -#include <sstream> - -#include "flatbuffers/util.h" -#include "src/compiler/schema_interface.h" -#include "src/compiler/ts_generator.h" - -namespace grpc_ts_generator { - -grpc::string ToDasherizedCase(const grpc::string pascal_case) { - std::string dasherized_case; - char p = 0; - for (size_t i = 0; i < pascal_case.length(); i++) { - char const &c = pascal_case[i]; - if (flatbuffers::is_alpha_upper(c)) { - if (i > 0 && p != flatbuffers::kPathSeparator) dasherized_case += "-"; - dasherized_case += flatbuffers::CharToLower(c); - } else { - dasherized_case += c; - } - p = c; - } - return dasherized_case; -} - -grpc::string GenerateNamespace(const std::vector<std::string> namepsace, - const std::string filename, - const bool include_separator) { - grpc::string path = ""; - if (include_separator) path += "."; - - for (auto it = namepsace.begin(); it < namepsace.end(); it++) { - if (include_separator) path += "/"; - path += include_separator ? ToDasherizedCase(*it) : *it + "_"; - } - - if (include_separator) path += "/"; - path += include_separator ? ToDasherizedCase(filename) : filename; - return path; -} - -// MARK: - Shared code - -void GenerateImports(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary, - const bool grpc_var_import) { - auto vars = *dictonary; - printer->Print( - "// Generated GRPC code for FlatBuffers TS *** DO NOT EDIT ***\n"); - printer->Print("import * as flatbuffers from 'flatbuffers';\n"); - - std::set<grpc::string> generated_imports; - - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - auto output = method->get_output_type_name(); - auto input = method->get_input_type_name(); - auto input_namespace = method->get_input_namespace_parts(); - - vars["OUTPUT"] = output; - vars["INPUT"] = input; - - if (generated_imports.find(output) == generated_imports.end()) { - generated_imports.insert(output); - vars["OUTPUT_DIR"] = - GenerateNamespace(method->get_output_namespace_parts(), output, true); - vars["Output_alias"] = GenerateNamespace( - method->get_output_namespace_parts(), output, false); - printer->Print( - vars, "import { $OUTPUT$ as $Output_alias$ } from '$OUTPUT_DIR$';\n"); - } - if (generated_imports.find(input) == generated_imports.end()) { - generated_imports.insert(input); - vars["INPUT_DIR"] = - GenerateNamespace(method->get_output_namespace_parts(), input, true); - vars["Input_alias"] = - GenerateNamespace(method->get_output_namespace_parts(), input, false); - printer->Print( - vars, "import { $INPUT$ as $Input_alias$ } from '$INPUT_DIR$';\n"); - } - } - printer->Print("\n"); - if (grpc_var_import) - printer->Print("var grpc = require('grpc');\n"); - else - printer->Print("import * as grpc from 'grpc';\n"); - printer->Print("\n"); -} - -// MARK: - Generate Main GRPC Code - -void GetStreamType(grpc_generator::Printer *printer, - const grpc_generator::Method *method, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - auto client_streaming = method->ClientStreaming() || method->BidiStreaming(); - auto server_streaming = method->ServerStreaming() || method->BidiStreaming(); - vars["ClientStreaming"] = client_streaming ? "true" : "false"; - vars["ServerStreaming"] = server_streaming ? "true" : "false"; - printer->Print(vars, "requestStream: $ClientStreaming$,\n"); - printer->Print(vars, "responseStream: $ServerStreaming$,\n"); -} - -void GenerateSerializeMethod(grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, "function serialize_$Type$(buffer_args) {\n"); - printer->Indent(); - printer->Print(vars, "if (!(buffer_args instanceof $Type$)) {\n"); - printer->Indent(); - printer->Print(vars, - "throw new Error('Expected argument of type $VALUE$');\n"); - printer->Outdent(); - printer->Print("}\n"); - printer->Print(vars, "return buffer_args.serialize();\n"); - printer->Outdent(); - printer->Print("}\n\n"); -} - -void GenerateDeserializeMethod( - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, "function deserialize_$Type$(buffer) {\n"); - printer->Indent(); - printer->Print(vars, - "return $Type$.getRootAs$VALUE$(new " - "flatbuffers.ByteBuffer(buffer))\n"); - printer->Outdent(); - printer->Print("}\n\n"); -} - -void GenerateMethods(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - - std::set<grpc::string> generated_functions; - - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - auto output = method->get_output_type_name(); - auto input = method->get_input_type_name(); - - if (generated_functions.find(output) == generated_functions.end()) { - generated_functions.insert(output); - vars["VALUE"] = output; - vars["Type"] = GenerateNamespace(method->get_output_namespace_parts(), - output, false); - GenerateSerializeMethod(printer, &vars); - GenerateDeserializeMethod(printer, &vars); - } - printer->Print("\n"); - if (generated_functions.find(input) == generated_functions.end()) { - generated_functions.insert(input); - vars["VALUE"] = input; - vars["Type"] = - GenerateNamespace(method->get_input_namespace_parts(), input, false); - GenerateSerializeMethod(printer, &vars); - GenerateDeserializeMethod(printer, &vars); - } - } -} - -void GenerateService(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - vars["NAME"] = service->name() + "Service"; - - printer->Print(vars, "var $NAME$ = exports.$NAME$ = {\n"); - printer->Indent(); - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["MethodName"] = method->name(); - vars["OUTPUT"] = GenerateNamespace(method->get_output_namespace_parts(), - method->get_output_type_name(), false); - vars["INPUT"] = GenerateNamespace(method->get_input_namespace_parts(), - method->get_input_type_name(), false); - printer->Print(vars, "$MethodName$: {\n"); - printer->Indent(); - printer->Print(vars, "path: '/$PATH$$ServiceName$/$MethodName$',\n"); - GetStreamType(printer, &*method, &vars); - printer->Print(vars, "requestType: flatbuffers.ByteBuffer,\n"); - printer->Print(vars, "responseType: $OUTPUT$,\n"); - printer->Print(vars, "requestSerialize: serialize_$INPUT$,\n"); - printer->Print(vars, "requestDeserialize: deserialize_$INPUT$,\n"); - printer->Print(vars, "responseSerialize: serialize_$OUTPUT$,\n"); - printer->Print(vars, "responseDeserialize: deserialize_$OUTPUT$,\n"); - printer->Outdent(); - printer->Print("},\n"); - } - printer->Outdent(); - printer->Print("};\n"); - printer->Print(vars, - "exports.$ServiceName$Client = " - "grpc.makeGenericClientConstructor($NAME$);"); -} - -grpc::string Generate(grpc_generator::File *file, - const grpc_generator::Service *service, - const grpc::string &filename) { - grpc::string output; - std::map<grpc::string, grpc::string> vars; - - vars["PATH"] = file->package(); - - if (!file->package().empty()) { vars["PATH"].append("."); } - - vars["ServiceName"] = service->name(); - vars["FBSFile"] = service->name() + "_fbs"; - vars["Filename"] = filename; - auto printer = file->CreatePrinter(&output); - - GenerateImports(service, &*printer, &vars, true); - GenerateMethods(service, &*printer, &vars); - GenerateService(service, &*printer, &vars); - return output; -} - -// MARK: - Generate Interface - -void FillInterface(grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, - "interface I$ServiceName$Service_I$MethodName$ extends " - "grpc.MethodDefinition<$INPUT$, $OUTPUT$> {\n"); - printer->Indent(); - printer->Print(vars, "path: string; // /$PATH$$ServiceName$/$MethodName$\n"); - printer->Print(vars, "requestStream: boolean; // $ClientStreaming$\n"); - printer->Print(vars, "responseStream: boolean; // $ServerStreaming$\n"); - printer->Print(vars, "requestSerialize: grpc.serialize<$INPUT$>;\n"); - printer->Print(vars, "requestDeserialize: grpc.deserialize<$INPUT$>;\n"); - printer->Print(vars, "responseSerialize: grpc.serialize<$OUTPUT$>;\n"); - printer->Print(vars, "responseDeserialize: grpc.deserialize<$OUTPUT$>;\n"); - printer->Outdent(); - printer->Print("}\n"); -} - -void GenerateInterfaces(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - auto client_streaming = - method->ClientStreaming() || method->BidiStreaming(); - auto server_streaming = - method->ServerStreaming() || method->BidiStreaming(); - vars["ClientStreaming"] = client_streaming ? "true" : "false"; - vars["ServerStreaming"] = server_streaming ? "true" : "false"; - vars["MethodName"] = method->name(); - vars["OUTPUT"] = GenerateNamespace(method->get_output_namespace_parts(), - method->get_output_type_name(), false); - vars["INPUT"] = GenerateNamespace(method->get_input_namespace_parts(), - method->get_input_type_name(), false); - FillInterface(printer, &vars); - printer->Print("\n"); - } -} - -void GenerateExportedInterface( - const grpc_generator::Service *service, grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, "export interface I$ServiceName$Server {\n"); - printer->Indent(); - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["Name"] = method->name(); - vars["OUTPUT"] = GenerateNamespace(method->get_output_namespace_parts(), - method->get_output_type_name(), false); - vars["INPUT"] = GenerateNamespace(method->get_input_namespace_parts(), - method->get_input_type_name(), false); - if (method->BidiStreaming()) { - printer->Print(vars, - "$Name$: grpc.handleBidiStreamingCall<$INPUT$, " - "$OUTPUT$>;\n"); - continue; - } - if (method->NoStreaming()) { - printer->Print(vars, - "$Name$: grpc.handleUnaryCall<$INPUT$, " - "$OUTPUT$>;\n"); - continue; - } - if (method->ClientStreaming()) { - printer->Print(vars, - "$Name$: grpc.handleClientStreamingCall<$INPUT$, " - "$OUTPUT$>;\n"); - continue; - } - if (method->ServerStreaming()) { - printer->Print(vars, - "$Name$: grpc.handleServerStreamingCall<$INPUT$, " - "$OUTPUT$>;\n"); - continue; - } - } - printer->Outdent(); - printer->Print("}\n"); -} - -void GenerateMainInterface(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print( - vars, - "interface I$ServiceName$Service extends " - "grpc.ServiceDefinition<grpc.UntypedServiceImplementation> {\n"); - printer->Indent(); - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["MethodName"] = method->name(); - printer->Print(vars, - "$MethodName$: I$ServiceName$Service_I$MethodName$;\n"); - } - printer->Outdent(); - printer->Print("}\n"); - GenerateInterfaces(service, printer, &vars); - printer->Print("\n"); - printer->Print(vars, - "export const $ServiceName$Service: I$ServiceName$Service;\n"); - printer->Print("\n"); - GenerateExportedInterface(service, printer, &vars); -} - -grpc::string GenerateMetaData() { return "metadata: grpc.Metadata"; } - -grpc::string GenerateOptions() { return "options: Partial<grpc.CallOptions>"; } - -void GenerateUnaryClientInterface( - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - grpc::string main = "$ISPUBLIC$$MethodName$(request: $INPUT$, "; - grpc::string callback = - "callback: (error: grpc.ServiceError | null, response: " - "$OUTPUT$) => void): grpc.ClientUnaryCall;\n"; - auto meta_data = GenerateMetaData() + ", "; - auto options = GenerateOptions() + ", "; - printer->Print(vars, (main + callback).c_str()); - printer->Print(vars, (main + meta_data + callback).c_str()); - printer->Print(vars, (main + meta_data + options + callback).c_str()); -} - -void GenerateClientWriteStreamInterface( - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - grpc::string main = "$ISPUBLIC$$MethodName$("; - grpc::string callback = - "callback: (error: grpc.ServiceError | null, response: " - "$INPUT$) => void): " - "grpc.ClientWritableStream<$OUTPUT$>;\n"; - auto meta_data = GenerateMetaData() + ", "; - auto options = GenerateOptions() + ", "; - printer->Print(vars, (main + callback).c_str()); - printer->Print(vars, (main + meta_data + callback).c_str()); - printer->Print(vars, (main + options + callback).c_str()); - printer->Print(vars, (main + meta_data + options + callback).c_str()); -} - -void GenerateClientReadableStreamInterface( - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - grpc::string main = "$ISPUBLIC$$MethodName$(request: $INPUT$, "; - grpc::string end_function = "): grpc.ClientReadableStream<$OUTPUT$>;\n"; - auto meta_data = GenerateMetaData(); - auto options = GenerateOptions(); - printer->Print(vars, (main + meta_data + end_function).c_str()); - printer->Print(vars, (main + options + end_function).c_str()); -} - -void GenerateDepluxStreamInterface( - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - grpc::string main = "$ISPUBLIC$$MethodName$("; - grpc::string end_function = - "): grpc.ClientDuplexStream<$INPUT$, $OUTPUT$>;\n"; - auto meta_data = GenerateMetaData(); - auto options = GenerateOptions(); - printer->Print(vars, (main + end_function).c_str()); - printer->Print(vars, (main + options + end_function).c_str()); - printer->Print(vars, (main + meta_data + - ", options?: Partial<grpc.CallOptions>" + end_function) - .c_str()); -} - -void GenerateClientInterface(const grpc_generator::Service *service, - grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, "export interface I$ServiceName$Client {\n"); - printer->Indent(); - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["MethodName"] = method->name(); - vars["OUTPUT"] = GenerateNamespace(method->get_output_namespace_parts(), - method->get_output_type_name(), false); - vars["INPUT"] = GenerateNamespace(method->get_input_namespace_parts(), - method->get_input_type_name(), false); - vars["ISPUBLIC"] = ""; - - if (method->NoStreaming()) { - GenerateUnaryClientInterface(printer, &vars); - continue; - } - if (method->BidiStreaming()) { - GenerateDepluxStreamInterface(printer, &vars); - continue; - } - - if (method->ClientStreaming()) { - GenerateClientWriteStreamInterface(printer, &vars); - continue; - } - - if (method->ServerStreaming()) { - GenerateClientReadableStreamInterface(printer, &vars); - continue; - } - } - printer->Outdent(); - printer->Print("}\n"); -} - -void GenerateClientClassInterface( - const grpc_generator::Service *service, grpc_generator::Printer *printer, - std::map<grpc::string, grpc::string> *dictonary) { - auto vars = *dictonary; - printer->Print(vars, - "export class $ServiceName$Client extends grpc.Client " - "implements I$ServiceName$Client {\n"); - printer->Indent(); - printer->Print( - "constructor(address: string, credentials: grpc.ChannelCredentials, " - "options?: object);"); - for (auto it = 0; it < service->method_count(); it++) { - auto method = service->method(it); - vars["MethodName"] = method->name(); - vars["OUTPUT"] = GenerateNamespace(method->get_output_namespace_parts(), - method->get_output_type_name(), false); - vars["INPUT"] = GenerateNamespace(method->get_input_namespace_parts(), - method->get_input_type_name(), false); - vars["ISPUBLIC"] = "public "; - if (method->NoStreaming()) { - GenerateUnaryClientInterface(printer, &vars); - continue; - } - if (method->BidiStreaming()) { - GenerateDepluxStreamInterface(printer, &vars); - continue; - } - - if (method->ClientStreaming()) { - GenerateClientWriteStreamInterface(printer, &vars); - continue; - } - - if (method->ServerStreaming()) { - GenerateClientReadableStreamInterface(printer, &vars); - continue; - } - } - printer->Outdent(); - printer->Print("}\n"); -} - -grpc::string GenerateInterface(grpc_generator::File *file, - const grpc_generator::Service *service, - const grpc::string &filename) { - grpc::string output; - - std::set<grpc::string> generated_functions; - std::map<grpc::string, grpc::string> vars; - - vars["PATH"] = file->package(); - - if (!file->package().empty()) { vars["PATH"].append("."); } - - vars["ServiceName"] = service->name(); - vars["FBSFile"] = service->name() + "_fbs"; - vars["Filename"] = filename; - auto printer = file->CreatePrinter(&output); - - GenerateImports(service, &*printer, &vars, false); - GenerateMainInterface(service, &*printer, &vars); - printer->Print("\n"); - GenerateClientInterface(service, &*printer, &vars); - printer->Print("\n"); - GenerateClientClassInterface(service, &*printer, &vars); - return output; -} -} // namespace grpc_ts_generator diff --git a/contrib/libs/flatbuffers/grpc/src/compiler/ts_generator.h b/contrib/libs/flatbuffers/grpc/src/compiler/ts_generator.h deleted file mode 100644 index a33bb3c5d2..0000000000 --- a/contrib/libs/flatbuffers/grpc/src/compiler/ts_generator.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * 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 "src/compiler/config.h" -#include "src/compiler/schema_interface.h" - -#ifndef GRPC_CUSTOM_STRING -# include <string> -# define GRPC_CUSTOM_STRING std::string -#endif - -namespace grpc { - -typedef GRPC_CUSTOM_STRING string; - -} // namespace grpc - -namespace grpc_ts_generator { -grpc::string Generate(grpc_generator::File *file, - const grpc_generator::Service *service, - const grpc::string &filename); - -grpc::string GenerateInterface(grpc_generator::File *file, - const grpc_generator::Service *service, - const grpc::string &filename); -} // namespace grpc_ts_generator - diff --git a/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h b/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h deleted file mode 100644 index 09b773a468..0000000000 --- a/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2014 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_CODE_GENERATORS_H_ -#define FLATBUFFERS_CODE_GENERATORS_H_ - -#include <map> -#include <sstream> - -#include "idl.h" - -namespace flatbuffers { - -// Utility class to assist in generating code through use of text templates. -// -// Example code: -// CodeWriter code("\t"); -// code.SetValue("NAME", "Foo"); -// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; -// code.SetValue("NAME", "Bar"); -// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; -// std::cout << code.ToString() << std::endl; -// -// Output: -// void Foo() { printf("%s", "Foo"); } -// void Bar() { printf("%s", "Bar"); } -class CodeWriter { - public: - CodeWriter(std::string pad = std::string()) - : pad_(pad), cur_ident_lvl_(0), ignore_ident_(false) {} - - // Clears the current "written" code. - void Clear() { - stream_.str(""); - stream_.clear(); - } - - // Associates a key with a value. All subsequent calls to operator+=, where - // the specified key is contained in {{ and }} delimiters will be replaced by - // the given value. - void SetValue(const std::string &key, const std::string &value) { - value_map_[key] = value; - } - - std::string GetValue(const std::string &key) const { - const auto it = value_map_.find(key); - return it == value_map_.end() ? "" : it->second; - } - - // Appends the given text to the generated code as well as a newline - // character. Any text within {{ and }} delimiters is replaced by values - // previously stored in the CodeWriter by calling SetValue above. The newline - // will be suppressed if the text ends with the \\ character. - void operator+=(std::string text); - - // Returns the current contents of the CodeWriter as a std::string. - std::string ToString() const { return stream_.str(); } - - // Increase ident level for writing code - void IncrementIdentLevel() { cur_ident_lvl_++; } - // Decrease ident level for writing code - void DecrementIdentLevel() { - if (cur_ident_lvl_) cur_ident_lvl_--; - } - - void SetPadding(const std::string &padding) { pad_ = padding; } - - private: - std::map<std::string, std::string> value_map_; - std::stringstream stream_; - std::string pad_; - int cur_ident_lvl_; - bool ignore_ident_; - - // Add ident padding (tab or space) based on ident level - void AppendIdent(std::stringstream &stream); -}; - -class BaseGenerator { - public: - virtual bool generate() = 0; - - static std::string NamespaceDir(const Parser &parser, const std::string &path, - const Namespace &ns, - const bool dasherize = false); - - static std::string ToDasherizedCase(const std::string pascal_case); - - std::string GeneratedFileName(const std::string &path, - const std::string &file_name, - const IDLOptions &options) const; - - protected: - BaseGenerator(const Parser &parser, const std::string &path, - const std::string &file_name, std::string qualifying_start, - std::string qualifying_separator, std::string default_extension) - : parser_(parser), - path_(path), - file_name_(file_name), - qualifying_start_(qualifying_start), - qualifying_separator_(qualifying_separator), - default_extension_(default_extension) {} - virtual ~BaseGenerator() {} - - // No copy/assign. - BaseGenerator &operator=(const BaseGenerator &); - BaseGenerator(const BaseGenerator &); - - std::string NamespaceDir(const Namespace &ns, - const bool dasherize = false) const; - - static const char *FlatBuffersGeneratedWarning(); - - static std::string FullNamespace(const char *separator, const Namespace &ns); - - static std::string LastNamespacePart(const Namespace &ns); - - // tracks the current namespace for early exit in WrapInNameSpace - // c++, java and csharp returns a different namespace from - // the following default (no early exit, always fully qualify), - // which works for js and php - virtual const Namespace *CurrentNameSpace() const { return nullptr; } - - // Ensure that a type is prefixed with its namespace even within - // its own namespace to avoid conflict between generated method - // names and similarly named classes or structs - std::string WrapInNameSpace(const Namespace *ns, - const std::string &name) const; - - std::string WrapInNameSpace(const Definition &def) const; - - std::string GetNameSpace(const Definition &def) const; - - const Parser &parser_; - const std::string &path_; - const std::string &file_name_; - const std::string qualifying_start_; - const std::string qualifying_separator_; - const std::string default_extension_; -}; - -struct CommentConfig { - const char *first_line; - const char *content_line_prefix; - const char *last_line; -}; - -extern void GenComment(const std::vector<std::string> &dc, - std::string *code_ptr, const CommentConfig *config, - const char *prefix = ""); - -class FloatConstantGenerator { - public: - virtual ~FloatConstantGenerator() {} - std::string GenFloatConstant(const FieldDef &field) const; - - private: - virtual std::string Value(double v, const std::string &src) const = 0; - virtual std::string Inf(double v) const = 0; - virtual std::string NaN(double v) const = 0; - - virtual std::string Value(float v, const std::string &src) const = 0; - virtual std::string Inf(float v) const = 0; - virtual std::string NaN(float v) const = 0; - - template<typename T> - std::string GenFloatConstantImpl(const FieldDef &field) const; -}; - -class SimpleFloatConstantGenerator : public FloatConstantGenerator { - public: - SimpleFloatConstantGenerator(const char *nan_number, - const char *pos_inf_number, - const char *neg_inf_number); - - private: - std::string Value(double v, - const std::string &src) const FLATBUFFERS_OVERRIDE; - std::string Inf(double v) const FLATBUFFERS_OVERRIDE; - std::string NaN(double v) const FLATBUFFERS_OVERRIDE; - - std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE; - std::string Inf(float v) const FLATBUFFERS_OVERRIDE; - std::string NaN(float v) const FLATBUFFERS_OVERRIDE; - - const std::string nan_number_; - const std::string pos_inf_number_; - const std::string neg_inf_number_; -}; - -// C++, C#, Java like generator. -class TypedFloatConstantGenerator : public FloatConstantGenerator { - public: - TypedFloatConstantGenerator(const char *double_prefix, - const char *single_prefix, const char *nan_number, - const char *pos_inf_number, - const char *neg_inf_number = ""); - - private: - std::string Value(double v, - const std::string &src) const FLATBUFFERS_OVERRIDE; - std::string Inf(double v) const FLATBUFFERS_OVERRIDE; - - std::string NaN(double v) const FLATBUFFERS_OVERRIDE; - - std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE; - std::string Inf(float v) const FLATBUFFERS_OVERRIDE; - std::string NaN(float v) const FLATBUFFERS_OVERRIDE; - - std::string MakeNaN(const std::string &prefix) const; - std::string MakeInf(bool neg, const std::string &prefix) const; - - const std::string double_prefix_; - const std::string single_prefix_; - const std::string nan_number_; - const std::string pos_inf_number_; - const std::string neg_inf_number_; -}; - -} // namespace flatbuffers - -#endif // FLATBUFFERS_CODE_GENERATORS_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers_iter.h b/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers_iter.h deleted file mode 100644 index a770983dca..0000000000 --- a/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers_iter.h +++ /dev/null @@ -1,640 +0,0 @@ -/* - * Copyright 2014 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_ITER_H_ -#define FLATBUFFERS_ITER_H_ - -#include "flatbuffers.h" -#include <optional> - -/// @file -namespace yandex { -namespace maps { -namespace flatbuffers_iter { - -#define FLATBUFFERS_FILE_IDENTIFIER_LENGTH 4 - -using flatbuffers::uoffset_t; -using flatbuffers::soffset_t; -using flatbuffers::voffset_t; -using flatbuffers::EndianScalar; - -// Wrapper for uoffset_t to allow safe template specialization. -template<typename T> struct Offset { - uoffset_t o; - Offset() : o(0) {} - Offset(uoffset_t _o) : o(_o) {} - Offset<void> Union() const { return Offset<void>(o); } -}; - -template<typename Iter> -inline bool hasContiguous(const Iter& spot, uoffset_t length) -{ - return spot.hasContiguous(length); -} - -inline bool hasContiguous(const uint8_t* /* spot */, uoffset_t /* length */) -{ - return true; -} - -template <typename Iter> -inline const uint8_t* getRawPointer(const Iter& spot) -{ - return spot.rawPointer(); -} - -inline const uint8_t* getRawPointer(const uint8_t* spot) -{ - return spot; -} - -template<typename T, typename Iter> -typename std::enable_if<sizeof(T) == 1, T>::type extractValue(const Iter& spot) -{ - typename std::remove_cv<T>::type ret; - std::memcpy(&ret, getRawPointer(spot), 1); - return ret; -} - -template<typename T, typename Iter> -typename std::enable_if<sizeof(T) != 1, T>::type extractValue(const Iter& spot) -{ - if (hasContiguous(spot, sizeof(T))) { - typename std::remove_cv<T>::type ret; - std::memcpy(&ret, getRawPointer(spot), sizeof(T)); - return ret; - } - Iter itr = spot; - alignas(T) uint8_t buf[sizeof(T)]; - for (std::size_t i = 0; i < sizeof(T); ++i) { - buf[i] = *itr; - ++itr; - } - return *reinterpret_cast<T*>(buf); -} - -template<typename T, typename Iter> T ReadScalar(Iter p) { - return EndianScalar(extractValue<T>(p)); -} - -// When we read serialized data from memory, in the case of most scalars, -// we want to just read T, but in the case of Offset, we want to actually -// perform the indirection and return a pointer. -// The template specialization below does just that. -// It is wrapped in a struct since function templates can't overload on the -// return type like this. -// The typedef is for the convenience of callers of this function -// (avoiding the need for a trailing return decltype) -template<typename T> struct IndirectHelper { - typedef T return_type; - typedef T mutable_return_type; - static const size_t element_stride = sizeof(T); - template<typename Iter> - static return_type Read(const Iter& p, uoffset_t i) { - return i ? EndianScalar(extractValue<return_type>(p+sizeof(return_type)*i)) : EndianScalar(extractValue<return_type>(p)); - } -}; -template<typename T> struct IndirectHelper<Offset<T>> { - typedef std::optional<T> return_type; - typedef std::optional<T> mutable_return_type; - static const size_t element_stride = sizeof(uoffset_t); - template<typename Iter> - static return_type Read(Iter p, uoffset_t i) { - p += i * sizeof(uoffset_t); - return return_type(T(p + ReadScalar<uoffset_t>(p))); - } -}; -template<typename T> struct IndirectHelper<const T *> { -}; - - -// An STL compatible iterator implementation for Vector below, effectively -// calling Get() for every element. -template<typename T, typename IT, typename Iter> -struct VectorIterator - : public std::iterator<std::random_access_iterator_tag, IT, uoffset_t> { - - typedef std::iterator<std::random_access_iterator_tag, IT, uoffset_t> super_type; - -public: - VectorIterator(const Iter& data, uoffset_t i) : - data_(data + IndirectHelper<T>::element_stride * i) {} - VectorIterator(const VectorIterator &other) : data_(other.data_) {} - #ifndef FLATBUFFERS_CPP98_STL - VectorIterator(VectorIterator &&other) : data_(std::move(other.data_)) {} - #endif - - VectorIterator &operator=(const VectorIterator &other) { - data_ = other.data_; - return *this; - } - - VectorIterator &operator=(VectorIterator &&other) { - data_ = other.data_; - return *this; - } - - bool operator==(const VectorIterator &other) const { - return data_ == other.data_; - } - - bool operator!=(const VectorIterator &other) const { - return data_ != other.data_; - } - - ptrdiff_t operator-(const VectorIterator &other) const { - return (data_ - other.data_) / IndirectHelper<T>::element_stride; - } - - typename super_type::value_type operator *() const { - return IndirectHelper<T>::Read(data_, 0); - } - - typename super_type::value_type operator->() const { - return IndirectHelper<T>::Read(data_, 0); - } - - VectorIterator &operator++() { - data_ += IndirectHelper<T>::element_stride; - return *this; - } - - VectorIterator operator++(int) { - VectorIterator temp(data_, 0); - data_ += IndirectHelper<T>::element_stride; - return temp; - } - - VectorIterator operator+(const uoffset_t &offset) { - return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride, 0); - } - - VectorIterator& operator+=(const uoffset_t &offset) { - data_ += offset * IndirectHelper<T>::element_stride; - return *this; - } - - VectorIterator &operator--() { - data_ -= IndirectHelper<T>::element_stride; - return *this; - } - - VectorIterator operator--(int) { - VectorIterator temp(data_, 0); - data_ -= IndirectHelper<T>::element_stride; - return temp; - } - - VectorIterator operator-(const uoffset_t &offset) { - return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride, 0); - } - - VectorIterator& operator-=(const uoffset_t &offset) { - data_ -= offset * IndirectHelper<T>::element_stride; - return *this; - } - -private: - Iter data_; -}; - -// This is used as a helper type for accessing vectors. -// Vector::data() assumes the vector elements start after the length field. -template<typename T, typename Iter> class Vector { -public: - typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type, Iter> - iterator; - typedef VectorIterator<T, typename IndirectHelper<T>::return_type, Iter> - const_iterator; - - Vector(Iter data): - data_(data) - {} - - uoffset_t size() const { return EndianScalar(extractValue<uoffset_t>(data_)); } - - // Deprecated: use size(). Here for backwards compatibility. - uoffset_t Length() const { return size(); } - - typedef typename IndirectHelper<T>::return_type return_type; - typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type; - - return_type Get(uoffset_t i) const { - assert(i < size()); - return IndirectHelper<T>::Read(Data(), i); - } - - return_type operator[](uoffset_t i) const { return Get(i); } - - // If this is a Vector of enums, T will be its storage type, not the enum - // type. This function makes it convenient to retrieve value with enum - // type E. - template<typename E> E GetEnum(uoffset_t i) const { - return static_cast<E>(Get(i)); - } - - const Iter GetStructFromOffset(size_t o) const { - return Data() + o; - } - - iterator begin() { return iterator(Data(), 0); } - const_iterator begin() const { return const_iterator(Data(), 0); } - - iterator end() { return iterator(Data(), size()); } - const_iterator end() const { return const_iterator(Data(), size()); } - - // The raw data in little endian format. Use with care. - const Iter Data() const { - return data_ + sizeof(uoffset_t); - } - - Iter Data() { - return data_ + sizeof(uoffset_t); - } - - template<typename K> return_type LookupByKey(K key) const { - auto search_result = std::lower_bound(begin(), end(), key, KeyCompare<K>); - - if (search_result == end() || (*search_result)->KeyCompareWithValue(key) != 0) { - return std::nullopt; // Key not found. - } - - return *search_result; - } - - operator Iter() const - { - return data_; - } - -protected: - Iter data_; - -private: - template<typename K> static int KeyCompare(const return_type& ap, const K& bp) { - return ap->KeyCompareWithValue(bp) < 0; - } -}; - -// Represent a vector much like the template above, but in this case we -// don't know what the element types are (used with reflection.h). -template <typename Iter> -class VectorOfAny { -public: - VectorOfAny(Iter data): - data_(data) - {} - - uoffset_t size() const { return EndianScalar(extractValue<uoffset_t>(data_)); } - - const Iter Data() const { - return data_; - } - Iter Data() { - return data_; - } -protected: - - Iter data_; -}; - -// Convenient helper function to get the length of any vector, regardless -// of wether it is null or not (the field is not set). -template<typename T, typename Iter> static inline size_t VectorLength(const std::optional<Vector<T, Iter>> &v) { - return v ? v->Length() : 0; -} - -template <typename Iter> struct String : public Vector<char, Iter> { - using Vector<char,Iter>::Vector; - using Vector<char,Iter>::data_; - - std::string str() const { - if (hasContiguous(data_, sizeof(uoffset_t) + this->Length())) - return std::string(reinterpret_cast<const char*>(getRawPointer(data_)) + sizeof(uoffset_t), this->Length()); - return std::string(this->begin(), this->begin() + this->Length()); } - - bool operator <(const String &o) const { - return str() < o.str(); - } -}; - -// Converts a Field ID to a virtual table offset. -inline voffset_t FieldIndexToOffset(voffset_t field_id) { - // Should correspond to what EndTable() below builds up. - const int fixed_fields = 2; // Vtable size and Object Size. - return static_cast<voffset_t>((field_id + fixed_fields) * sizeof(voffset_t)); -} - -/// @endcond - -/// @cond FLATBUFFERS_INTERNAL -template<typename T, typename Iter> std::optional<T> GetMutableRoot(Iter begin) { - flatbuffers::EndianCheck(); - return T(begin + EndianScalar(extractValue<uoffset_t>(begin))); -} - -template<typename T, typename Iter> std::optional<T> GetRoot(Iter begin) { - return GetMutableRoot<T, Iter>(begin); -} - -template<typename T, typename Iter> std::optional<T> GetSizePrefixedRoot(Iter buf) { - return GetRoot<T, Iter>(buf + sizeof(uoffset_t)); -} - -// Helper to see if the identifier in a buffer has the expected value. - -template <typename Iter> inline bool BufferHasIdentifier(const Iter& buf, const char *identifier) { - return std::equal( - identifier, - identifier + std::min(std::strlen(identifier) + 1, static_cast<std::size_t>(FLATBUFFERS_FILE_IDENTIFIER_LENGTH)), - buf + sizeof(uoffset_t)); -} - -// Helper class to verify the integrity of a FlatBuffer -template <typename Iter> -class Verifier FLATBUFFERS_FINAL_CLASS { - public: - Verifier(const Iter& buf, size_t buf_len, size_t _max_depth = 64, - size_t _max_tables = 1000000) - : buf_(buf), end_(buf + buf_len), depth_(0), max_depth_(_max_depth), - num_tables_(0), max_tables_(_max_tables) - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - , upper_bound_(buf) - #endif - {} - - // Central location where any verification failures register. - bool Check(bool ok) const { - #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE - assert(ok); - #endif - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - if (!ok) - upper_bound_ = buf_; - #endif - return ok; - } - - // Verify any range within the buffer. - bool Verify(const Iter& elem, size_t elem_len) const { - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - auto upper_bound = elem + elem_len; - if (upper_bound_ < upper_bound) - upper_bound_ = upper_bound; - #endif - return Check(elem_len <= (size_t) (end_ - buf_) && - elem >= buf_ && - elem <= end_ - elem_len); - } - - // Verify a range indicated by sizeof(T). - template<typename T> bool Verify(const Iter& elem) const { - return Verify(elem, sizeof(T)); - } - - template<typename T> bool VerifyTable(const std::optional<T>& table) { - return !table || table->Verify(*this); - } - - template<typename T> bool Verify(const std::optional<Vector<T, Iter>>& vec) const { - Iter end; - return !vec || - VerifyVector(static_cast<Iter>(*vec), sizeof(T), - &end); - } - - template<typename T> bool Verify(const std::optional<Vector<const T, Iter>>& vec) const { - return Verify(*reinterpret_cast<const std::optional<Vector<T, Iter>> *>(&vec)); - } - - bool Verify(const std::optional<String<Iter>>& str) const { - Iter end; - return !str || - (VerifyVector(static_cast<Iter>(*str), 1, &end) && - Verify(end, 1) && // Must have terminator - Check(*end == '\0')); // Terminating byte must be 0. - } - - // Common code between vectors and strings. - bool VerifyVector(const Iter& vec, size_t elem_size, - Iter *end) const { - // Check we can read the size field. - if (!Verify<uoffset_t>(vec)) return false; - // Check the whole array. If this is a string, the byte past the array - // must be 0. - auto size = ReadScalar<uoffset_t>(vec); - auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size; - if (!Check(size < max_elems)) - return false; // Protect against byte_size overflowing. - auto byte_size = sizeof(size) + elem_size * size; - *end = vec + byte_size; - return Verify(vec, byte_size); - } - - // Special case for string contents, after the above has been called. - bool VerifyVectorOfStrings(const std::optional<Vector<Offset<String<Iter>>, Iter>>& vec) const { - if (vec) { - for (uoffset_t i = 0; i < vec->size(); i++) { - if (!Verify(vec->Get(i))) return false; - } - } - return true; - } - - // Special case for table contents, after the above has been called. - template<typename T> bool VerifyVectorOfTables(const std::optional<Vector<Offset<T>, Iter>>& vec) { - if (vec) { - for (uoffset_t i = 0; i < vec->size(); i++) { - if (!vec->Get(i)->Verify(*this)) return false; - } - } - return true; - } - - template<typename T> bool VerifyBufferFromStart(const char *identifier, - const Iter& start) { - if (identifier && - (static_cast<std::size_t>(end_ - start) < 2 * sizeof(flatbuffers_iter::uoffset_t) || - !BufferHasIdentifier(start, identifier))) { - return false; - } - - // Call T::Verify, which must be in the generated code for this type. - return Verify<uoffset_t>(start) && - T(start + ReadScalar<uoffset_t>(start)). - Verify(*this) - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - && GetComputedSize() - #endif - ; - } - - // Verify this whole buffer, starting with root type T. - template<typename T> bool VerifyBuffer(const char *identifier) { - return VerifyBufferFromStart<T>(identifier, buf_); - } - - template<typename T> bool VerifySizePrefixedBuffer(const char *identifier) { - return Verify<uoffset_t>(buf_) && - ReadScalar<uoffset_t>(buf_) == end_ - buf_ - sizeof(uoffset_t) && - VerifyBufferFromStart<T>(identifier, buf_ + sizeof(uoffset_t)); - } - - // Called at the start of a table to increase counters measuring data - // structure depth and amount, and possibly bails out with false if - // limits set by the constructor have been hit. Needs to be balanced - // with EndTable(). - bool VerifyComplexity() { - depth_++; - num_tables_++; - return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_); - } - - // Called at the end of a table to pop the depth count. - bool EndTable() { - depth_--; - return true; - } - - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - // Returns the message size in bytes - size_t GetComputedSize() const { - uintptr_t size = upper_bound_ - buf_; - // Align the size to uoffset_t - size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1); - return (buf_ + size > end_) ? 0 : size; - } - #endif - - private: - const Iter buf_; - const Iter end_; - size_t depth_; - size_t max_depth_; - size_t num_tables_; - size_t max_tables_; -#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - mutable const Iter upper_bound_; -#endif -}; - -// "structs" are flat structures that do not have an offset table, thus -// always have all members present and do not support forwards/backwards -// compatible extensions. -template <typename Iter> -class Struct FLATBUFFERS_FINAL_CLASS { - public: - template<typename T> T GetField(uoffset_t o) const { - return ReadScalar<T>(data_ + o); - } - - template<typename T> T GetStruct(uoffset_t o) const { - return T(data_ + o); - } - - private: - Iter data_; -}; - -// "tables" use an offset table (possibly shared) that allows fields to be -// omitted and added at will, but uses an extra indirection to read. -template<typename Iter> -class Table { - public: - Table(Iter data): data_(data) {} - - const Iter GetVTable() const { - return data_ - ReadScalar<soffset_t>(data_); - } - - // This gets the field offset for any of the functions below it, or 0 - // if the field was not present. - voffset_t GetOptionalFieldOffset(voffset_t field) const { - // The vtable offset is always at the start. - auto vtable = GetVTable(); - // The first element is the size of the vtable (fields + type id + itself). - auto vtsize = ReadScalar<voffset_t>(vtable); - // If the field we're accessing is outside the vtable, we're reading older - // data, so it's the same as if the offset was 0 (not present). - return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0; - } - - template<typename T> T GetField(voffset_t field, T defaultval) const { - auto field_offset = GetOptionalFieldOffset(field); - return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval; - } - - template<typename P> std::optional<P> GetPointer(voffset_t field) { - auto field_offset = GetOptionalFieldOffset(field); - auto p = data_ + field_offset; - return field_offset ? std::optional<P>(P(p + ReadScalar<uoffset_t>(p))) : std::nullopt; - } - - template<typename P> std::optional<P> GetPointer(voffset_t field) const { - return const_cast<Table *>(this)->template GetPointer<P>(field); - } - - template<typename P> P GetStruct(voffset_t field) const { - auto field_offset = GetOptionalFieldOffset(field); - auto p = data_ + field_offset; - return extractValue<P>(p); - } - - bool CheckField(voffset_t field) const { - return GetOptionalFieldOffset(field) != 0; - } - - // Verify the vtable of this table. - // Call this once per table, followed by VerifyField once per field. - bool VerifyTableStart(Verifier<Iter> &verifier) const { - // Check the vtable offset. - if (!verifier.template Verify<soffset_t>(data_)) return false; - auto vtable = GetVTable(); - // Check the vtable size field, then check vtable fits in its entirety. - return verifier.VerifyComplexity() && - verifier.template Verify<voffset_t>(vtable) && - (ReadScalar<voffset_t>(vtable) & (sizeof(voffset_t) - 1)) == 0 && - verifier.Verify(vtable, ReadScalar<voffset_t>(vtable)); - } - - // Verify a particular field. - template<typename T> bool VerifyField(const Verifier<Iter> &verifier, - voffset_t field) const { - // Calling GetOptionalFieldOffset should be safe now thanks to - // VerifyTable(). - auto field_offset = GetOptionalFieldOffset(field); - // Check the actual field. - return !field_offset || verifier.template Verify<T>(data_ + field_offset); - } - - // VerifyField for required fields. - template<typename T> bool VerifyFieldRequired(const Verifier<Iter> &verifier, - voffset_t field) const { - auto field_offset = GetOptionalFieldOffset(field); - return verifier.Check(field_offset != 0) && - verifier.template Verify<T>(data_ + field_offset); - } - - private: - Iter data_; -}; -/// @endcond -} // namespace flatbuffers_iter -} // namespace maps -} // namespace yandex - -#endif // FLATBUFFERS_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flatc.h b/contrib/libs/flatbuffers/include/flatbuffers/flatc.h deleted file mode 100644 index 1466b3651d..0000000000 --- a/contrib/libs/flatbuffers/include/flatbuffers/flatc.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2017 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_FLATC_H_ -#define FLATBUFFERS_FLATC_H_ - -#include <functional> -#include <limits> -#include <string> - -#include "flatbuffers.h" -#include "idl.h" -#include "util.h" - -namespace flatbuffers { - -extern void LogCompilerWarn(const std::string &warn); -extern void LogCompilerError(const std::string &err); - -class FlatCompiler { - public: - // Output generator for the various programming languages and formats we - // support. - struct Generator { - typedef bool (*GenerateFn)(const flatbuffers::Parser &parser, - const std::string &path, - const std::string &file_name); - typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser, - const std::string &path, - const std::string &file_name); - - GenerateFn generate; - const char *generator_opt_short; - const char *generator_opt_long; - const char *lang_name; - bool schema_only; - GenerateFn generateGRPC; - flatbuffers::IDLOptions::Language lang; - const char *generator_help; - MakeRuleFn make_rule; - }; - - typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn, - bool show_exe_name); - - typedef void (*ErrorFn)(const FlatCompiler *flatc, const std::string &err, - bool usage, bool show_exe_name); - - // Parameters required to initialize the FlatCompiler. - struct InitParams { - InitParams() - : generators(nullptr), - num_generators(0), - warn_fn(nullptr), - error_fn(nullptr) {} - - const Generator *generators; - size_t num_generators; - WarnFn warn_fn; - ErrorFn error_fn; - }; - - explicit FlatCompiler(const InitParams ¶ms) : params_(params) {} - - int Compile(int argc, const char **argv); - - std::string GetUsageString(const char *program_name) const; - - private: - void ParseFile(flatbuffers::Parser &parser, const std::string &filename, - const std::string &contents, - std::vector<const char *> &include_directories) const; - - void LoadBinarySchema(Parser &parser, const std::string &filename, - const std::string &contents); - - void Warn(const std::string &warn, bool show_exe_name = true) const; - - void Error(const std::string &err, bool usage = true, - bool show_exe_name = true) const; - - InitParams params_; -}; - -} // namespace flatbuffers - -#endif // FLATBUFFERS_FLATC_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h b/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h deleted file mode 100644 index d855b67731..0000000000 --- a/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h +++ /dev/null @@ -1,1636 +0,0 @@ -/* - * Copyright 2017 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_FLEXBUFFERS_H_ -#define FLATBUFFERS_FLEXBUFFERS_H_ - -#include <map> -// Used to select STL variant. -#include "base.h" -// We use the basic binary writing functions from the regular FlatBuffers. -#include "util.h" - -#ifdef _MSC_VER -# include <intrin.h> -#endif - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4127) // C4127: conditional expression is constant -#endif - -namespace flexbuffers { - -class Reference; -class Map; - -// These are used in the lower 2 bits of a type field to determine the size of -// the elements (and or size field) of the item pointed to (e.g. vector). -enum BitWidth { - BIT_WIDTH_8 = 0, - BIT_WIDTH_16 = 1, - BIT_WIDTH_32 = 2, - BIT_WIDTH_64 = 3, -}; - -// These are used as the upper 6 bits of a type field to indicate the actual -// type. -enum Type { - FBT_NULL = 0, - FBT_INT = 1, - FBT_UINT = 2, - FBT_FLOAT = 3, - // Types above stored inline, types below store an offset. - FBT_KEY = 4, - FBT_STRING = 5, - FBT_INDIRECT_INT = 6, - FBT_INDIRECT_UINT = 7, - FBT_INDIRECT_FLOAT = 8, - FBT_MAP = 9, - FBT_VECTOR = 10, // Untyped. - FBT_VECTOR_INT = 11, // Typed any size (stores no type table). - FBT_VECTOR_UINT = 12, - FBT_VECTOR_FLOAT = 13, - FBT_VECTOR_KEY = 14, - // DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead. - // Read test.cpp/FlexBuffersDeprecatedTest() for details on why. - FBT_VECTOR_STRING_DEPRECATED = 15, - FBT_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field). - FBT_VECTOR_UINT2 = 17, - FBT_VECTOR_FLOAT2 = 18, - FBT_VECTOR_INT3 = 19, // Typed triple (no type table, no size field). - FBT_VECTOR_UINT3 = 20, - FBT_VECTOR_FLOAT3 = 21, - FBT_VECTOR_INT4 = 22, // Typed quad (no type table, no size field). - FBT_VECTOR_UINT4 = 23, - FBT_VECTOR_FLOAT4 = 24, - FBT_BLOB = 25, - FBT_BOOL = 26, - FBT_VECTOR_BOOL = - 36, // To Allow the same type of conversion of type to vector type -}; - -inline bool IsInline(Type t) { return t <= FBT_FLOAT || t == FBT_BOOL; } - -inline bool IsTypedVectorElementType(Type t) { - return (t >= FBT_INT && t <= FBT_STRING) || t == FBT_BOOL; -} - -inline bool IsTypedVector(Type t) { - return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING_DEPRECATED) || - t == FBT_VECTOR_BOOL; -} - -inline bool IsFixedTypedVector(Type t) { - return t >= FBT_VECTOR_INT2 && t <= FBT_VECTOR_FLOAT4; -} - -inline Type ToTypedVector(Type t, size_t fixed_len = 0) { - FLATBUFFERS_ASSERT(IsTypedVectorElementType(t)); - switch (fixed_len) { - case 0: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT); - case 2: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT2); - case 3: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT3); - case 4: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT4); - default: FLATBUFFERS_ASSERT(0); return FBT_NULL; - } -} - -inline Type ToTypedVectorElementType(Type t) { - FLATBUFFERS_ASSERT(IsTypedVector(t)); - return static_cast<Type>(t - FBT_VECTOR_INT + FBT_INT); -} - -inline Type ToFixedTypedVectorElementType(Type t, uint8_t *len) { - FLATBUFFERS_ASSERT(IsFixedTypedVector(t)); - auto fixed_type = t - FBT_VECTOR_INT2; - *len = static_cast<uint8_t>(fixed_type / 3 + - 2); // 3 types each, starting from length 2. - return static_cast<Type>(fixed_type % 3 + FBT_INT); -} - -// TODO: implement proper support for 8/16bit floats, or decide not to -// support them. -typedef int16_t half; -typedef int8_t quarter; - -// TODO: can we do this without conditionals using intrinsics or inline asm -// on some platforms? Given branch prediction the method below should be -// decently quick, but it is the most frequently executed function. -// We could do an (unaligned) 64-bit read if we ifdef out the platforms for -// which that doesn't work (or where we'd read into un-owned memory). -template<typename R, typename T1, typename T2, typename T4, typename T8> -R ReadSizedScalar(const uint8_t *data, uint8_t byte_width) { - return byte_width < 4 - ? (byte_width < 2 - ? static_cast<R>(flatbuffers::ReadScalar<T1>(data)) - : static_cast<R>(flatbuffers::ReadScalar<T2>(data))) - : (byte_width < 8 - ? static_cast<R>(flatbuffers::ReadScalar<T4>(data)) - : static_cast<R>(flatbuffers::ReadScalar<T8>(data))); -} - -inline int64_t ReadInt64(const uint8_t *data, uint8_t byte_width) { - return ReadSizedScalar<int64_t, int8_t, int16_t, int32_t, int64_t>( - data, byte_width); -} - -inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) { - // This is the "hottest" function (all offset lookups use this), so worth - // optimizing if possible. - // TODO: GCC apparently replaces memcpy by a rep movsb, but only if count is a - // constant, which here it isn't. Test if memcpy is still faster than - // the conditionals in ReadSizedScalar. Can also use inline asm. - // clang-format off - #if defined(_MSC_VER) && ((defined(_M_X64) && !defined(_M_ARM64EC)) || defined _M_IX86) - uint64_t u = 0; - __movsb(reinterpret_cast<uint8_t *>(&u), - reinterpret_cast<const uint8_t *>(data), byte_width); - return flatbuffers::EndianScalar(u); - #else - return ReadSizedScalar<uint64_t, uint8_t, uint16_t, uint32_t, uint64_t>( - data, byte_width); - #endif - // clang-format on -} - -inline double ReadDouble(const uint8_t *data, uint8_t byte_width) { - return ReadSizedScalar<double, quarter, half, float, double>(data, - byte_width); -} - -inline const uint8_t *Indirect(const uint8_t *offset, uint8_t byte_width) { - return offset - ReadUInt64(offset, byte_width); -} - -template<typename T> const uint8_t *Indirect(const uint8_t *offset) { - return offset - flatbuffers::ReadScalar<T>(offset); -} - -inline BitWidth WidthU(uint64_t u) { -#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width) \ - { \ - if (!((u) & ~((1ULL << (width)) - 1ULL))) return BIT_WIDTH_##width; \ - } - FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 8); - FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 16); - FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 32); -#undef FLATBUFFERS_GET_FIELD_BIT_WIDTH - return BIT_WIDTH_64; -} - -inline BitWidth WidthI(int64_t i) { - auto u = static_cast<uint64_t>(i) << 1; - return WidthU(i >= 0 ? u : ~u); -} - -inline BitWidth WidthF(double f) { - return static_cast<double>(static_cast<float>(f)) == f ? BIT_WIDTH_32 - : BIT_WIDTH_64; -} - -// Base class of all types below. -// Points into the data buffer and allows access to one type. -class Object { - public: - Object(const uint8_t *data, uint8_t byte_width) - : data_(data), byte_width_(byte_width) {} - - protected: - const uint8_t *data_; - uint8_t byte_width_; -}; - -// Object that has a size, obtained either from size prefix, or elsewhere. -class Sized : public Object { - public: - // Size prefix. - Sized(const uint8_t *data, uint8_t byte_width) - : Object(data, byte_width), size_(read_size()) {} - // Manual size. - Sized(const uint8_t *data, uint8_t byte_width, size_t sz) - : Object(data, byte_width), size_(sz) {} - size_t size() const { return size_; } - // Access size stored in `byte_width_` bytes before data_ pointer. - size_t read_size() const { - return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_)); - } - - protected: - size_t size_; -}; - -class String : public Sized { - public: - // Size prefix. - String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {} - // Manual size. - String(const uint8_t *data, uint8_t byte_width, size_t sz) - : Sized(data, byte_width, sz) {} - - size_t length() const { return size(); } - const char *c_str() const { return reinterpret_cast<const char *>(data_); } - std::string str() const { return std::string(c_str(), size()); } - - static String EmptyString() { - static const char *empty_string = ""; - return String(reinterpret_cast<const uint8_t *>(empty_string), 1, 0); - } - bool IsTheEmptyString() const { return data_ == EmptyString().data_; } -}; - -class Blob : public Sized { - public: - Blob(const uint8_t *data_buf, uint8_t byte_width) - : Sized(data_buf, byte_width) {} - - static Blob EmptyBlob() { - static const uint8_t empty_blob[] = { 0 /*len*/ }; - return Blob(empty_blob + 1, 1); - } - bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; } - const uint8_t *data() const { return data_; } -}; - -class Vector : public Sized { - public: - Vector(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {} - - Reference operator[](size_t i) const; - - static Vector EmptyVector() { - static const uint8_t empty_vector[] = { 0 /*len*/ }; - return Vector(empty_vector + 1, 1); - } - bool IsTheEmptyVector() const { return data_ == EmptyVector().data_; } -}; - -class TypedVector : public Sized { - public: - TypedVector(const uint8_t *data, uint8_t byte_width, Type element_type) - : Sized(data, byte_width), type_(element_type) {} - - Reference operator[](size_t i) const; - - static TypedVector EmptyTypedVector() { - static const uint8_t empty_typed_vector[] = { 0 /*len*/ }; - return TypedVector(empty_typed_vector + 1, 1, FBT_INT); - } - bool IsTheEmptyVector() const { - return data_ == TypedVector::EmptyTypedVector().data_; - } - - Type ElementType() { return type_; } - - friend Reference; - - private: - Type type_; - - friend Map; -}; - -class FixedTypedVector : public Object { - public: - FixedTypedVector(const uint8_t *data, uint8_t byte_width, Type element_type, - uint8_t len) - : Object(data, byte_width), type_(element_type), len_(len) {} - - Reference operator[](size_t i) const; - - static FixedTypedVector EmptyFixedTypedVector() { - static const uint8_t fixed_empty_vector[] = { 0 /* unused */ }; - return FixedTypedVector(fixed_empty_vector, 1, FBT_INT, 0); - } - bool IsTheEmptyFixedTypedVector() const { - return data_ == FixedTypedVector::EmptyFixedTypedVector().data_; - } - - Type ElementType() { return type_; } - uint8_t size() { return len_; } - - private: - Type type_; - uint8_t len_; -}; - -class Map : public Vector { - public: - Map(const uint8_t *data, uint8_t byte_width) : Vector(data, byte_width) {} - - Reference operator[](const char *key) const; - Reference operator[](const std::string &key) const; - - Vector Values() const { return Vector(data_, byte_width_); } - - TypedVector Keys() const { - const size_t num_prefixed_fields = 3; - auto keys_offset = data_ - byte_width_ * num_prefixed_fields; - return TypedVector(Indirect(keys_offset, byte_width_), - static_cast<uint8_t>( - ReadUInt64(keys_offset + byte_width_, byte_width_)), - FBT_KEY); - } - - static Map EmptyMap() { - static const uint8_t empty_map[] = { - 0 /*keys_len*/, 0 /*keys_offset*/, 1 /*keys_width*/, 0 /*len*/ - }; - return Map(empty_map + 4, 1); - } - - bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; } -}; - -template<typename T> -void AppendToString(std::string &s, T &&v, bool keys_quoted) { - s += "[ "; - for (size_t i = 0; i < v.size(); i++) { - if (i) s += ", "; - v[i].ToString(true, keys_quoted, s); - } - s += " ]"; -} - -class Reference { - public: - Reference() - : data_(nullptr), - parent_width_(0), - byte_width_(BIT_WIDTH_8), - type_(FBT_NULL) {} - - Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width, - Type type) - : data_(data), - parent_width_(parent_width), - byte_width_(byte_width), - type_(type) {} - - Reference(const uint8_t *data, uint8_t parent_width, uint8_t packed_type) - : data_(data), parent_width_(parent_width) { - byte_width_ = 1U << static_cast<BitWidth>(packed_type & 3); - type_ = static_cast<Type>(packed_type >> 2); - } - - Type GetType() const { return type_; } - - bool IsNull() const { return type_ == FBT_NULL; } - bool IsBool() const { return type_ == FBT_BOOL; } - bool IsInt() const { return type_ == FBT_INT || type_ == FBT_INDIRECT_INT; } - bool IsUInt() const { - return type_ == FBT_UINT || type_ == FBT_INDIRECT_UINT; - } - bool IsIntOrUint() const { return IsInt() || IsUInt(); } - bool IsFloat() const { - return type_ == FBT_FLOAT || type_ == FBT_INDIRECT_FLOAT; - } - bool IsNumeric() const { return IsIntOrUint() || IsFloat(); } - bool IsString() const { return type_ == FBT_STRING; } - bool IsKey() const { return type_ == FBT_KEY; } - bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; } - bool IsUntypedVector() const { return type_ == FBT_VECTOR; } - bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); } - bool IsFixedTypedVector() const { - return flexbuffers::IsFixedTypedVector(type_); - } - bool IsAnyVector() const { - return (IsTypedVector() || IsFixedTypedVector() || IsVector()); - } - bool IsMap() const { return type_ == FBT_MAP; } - bool IsBlob() const { return type_ == FBT_BLOB; } - bool AsBool() const { - return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_) - : AsUInt64()) != 0; - } - - // Reads any type as a int64_t. Never fails, does most sensible conversion. - // Truncates floats, strings are attempted to be parsed for a number, - // vectors/maps return their size. Returns 0 if all else fails. - int64_t AsInt64() const { - if (type_ == FBT_INT) { - // A fast path for the common case. - return ReadInt64(data_, parent_width_); - } else - switch (type_) { - case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); - case FBT_UINT: return ReadUInt64(data_, parent_width_); - case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); - case FBT_FLOAT: - return static_cast<int64_t>(ReadDouble(data_, parent_width_)); - case FBT_INDIRECT_FLOAT: - return static_cast<int64_t>(ReadDouble(Indirect(), byte_width_)); - case FBT_NULL: return 0; - case FBT_STRING: return flatbuffers::StringToInt(AsString().c_str()); - case FBT_VECTOR: return static_cast<int64_t>(AsVector().size()); - case FBT_BOOL: return ReadInt64(data_, parent_width_); - default: - // Convert other things to int. - return 0; - } - } - - // TODO: could specialize these to not use AsInt64() if that saves - // extension ops in generated code, and use a faster op than ReadInt64. - int32_t AsInt32() const { return static_cast<int32_t>(AsInt64()); } - int16_t AsInt16() const { return static_cast<int16_t>(AsInt64()); } - int8_t AsInt8() const { return static_cast<int8_t>(AsInt64()); } - - uint64_t AsUInt64() const { - if (type_ == FBT_UINT) { - // A fast path for the common case. - return ReadUInt64(data_, parent_width_); - } else - switch (type_) { - case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); - case FBT_INT: return ReadInt64(data_, parent_width_); - case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); - case FBT_FLOAT: - return static_cast<uint64_t>(ReadDouble(data_, parent_width_)); - case FBT_INDIRECT_FLOAT: - return static_cast<uint64_t>(ReadDouble(Indirect(), byte_width_)); - case FBT_NULL: return 0; - case FBT_STRING: return flatbuffers::StringToUInt(AsString().c_str()); - case FBT_VECTOR: return static_cast<uint64_t>(AsVector().size()); - case FBT_BOOL: return ReadUInt64(data_, parent_width_); - default: - // Convert other things to uint. - return 0; - } - } - - uint32_t AsUInt32() const { return static_cast<uint32_t>(AsUInt64()); } - uint16_t AsUInt16() const { return static_cast<uint16_t>(AsUInt64()); } - uint8_t AsUInt8() const { return static_cast<uint8_t>(AsUInt64()); } - - double AsDouble() const { - if (type_ == FBT_FLOAT) { - // A fast path for the common case. - return ReadDouble(data_, parent_width_); - } else - switch (type_) { - case FBT_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_); - case FBT_INT: - return static_cast<double>(ReadInt64(data_, parent_width_)); - case FBT_UINT: - return static_cast<double>(ReadUInt64(data_, parent_width_)); - case FBT_INDIRECT_INT: - return static_cast<double>(ReadInt64(Indirect(), byte_width_)); - case FBT_INDIRECT_UINT: - return static_cast<double>(ReadUInt64(Indirect(), byte_width_)); - case FBT_NULL: return 0.0; - case FBT_STRING: { - double d; - flatbuffers::StringToNumber(AsString().c_str(), &d); - return d; - } - case FBT_VECTOR: return static_cast<double>(AsVector().size()); - case FBT_BOOL: - return static_cast<double>(ReadUInt64(data_, parent_width_)); - default: - // Convert strings and other things to float. - return 0; - } - } - - float AsFloat() const { return static_cast<float>(AsDouble()); } - - const char *AsKey() const { - if (type_ == FBT_KEY || type_ == FBT_STRING) { - return reinterpret_cast<const char *>(Indirect()); - } else { - return ""; - } - } - - // This function returns the empty string if you try to read something that - // is not a string or key. - String AsString() const { - if (type_ == FBT_STRING) { - return String(Indirect(), byte_width_); - } else if (type_ == FBT_KEY) { - auto key = Indirect(); - return String(key, byte_width_, - strlen(reinterpret_cast<const char *>(key))); - } else { - return String::EmptyString(); - } - } - - // Unlike AsString(), this will convert any type to a std::string. - std::string ToString() const { - std::string s; - ToString(false, false, s); - return s; - } - - // Convert any type to a JSON-like string. strings_quoted determines if - // string values at the top level receive "" quotes (inside other values - // they always do). keys_quoted determines if keys are quoted, at any level. - // TODO(wvo): add further options to have indentation/newlines. - void ToString(bool strings_quoted, bool keys_quoted, std::string &s) const { - if (type_ == FBT_STRING) { - String str(Indirect(), byte_width_); - if (strings_quoted) { - flatbuffers::EscapeString(str.c_str(), str.length(), &s, true, false); - } else { - s.append(str.c_str(), str.length()); - } - } else if (IsKey()) { - auto str = AsKey(); - if (keys_quoted) { - flatbuffers::EscapeString(str, strlen(str), &s, true, false); - } else { - s += str; - } - } else if (IsInt()) { - s += flatbuffers::NumToString(AsInt64()); - } else if (IsUInt()) { - s += flatbuffers::NumToString(AsUInt64()); - } else if (IsFloat()) { - s += flatbuffers::NumToString(AsDouble()); - } else if (IsNull()) { - s += "null"; - } else if (IsBool()) { - s += AsBool() ? "true" : "false"; - } else if (IsMap()) { - s += "{ "; - auto m = AsMap(); - auto keys = m.Keys(); - auto vals = m.Values(); - for (size_t i = 0; i < keys.size(); i++) { - keys[i].ToString(true, keys_quoted, s); - s += ": "; - vals[i].ToString(true, keys_quoted, s); - if (i < keys.size() - 1) s += ", "; - } - s += " }"; - } else if (IsVector()) { - AppendToString<Vector>(s, AsVector(), keys_quoted); - } else if (IsTypedVector()) { - AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted); - } else if (IsFixedTypedVector()) { - AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted); - } else if (IsBlob()) { - auto blob = AsBlob(); - flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()), - blob.size(), &s, true, false); - } else { - s += "(?)"; - } - } - - // This function returns the empty blob if you try to read a not-blob. - // Strings can be viewed as blobs too. - Blob AsBlob() const { - if (type_ == FBT_BLOB || type_ == FBT_STRING) { - return Blob(Indirect(), byte_width_); - } else { - return Blob::EmptyBlob(); - } - } - - // This function returns the empty vector if you try to read a not-vector. - // Maps can be viewed as vectors too. - Vector AsVector() const { - if (type_ == FBT_VECTOR || type_ == FBT_MAP) { - return Vector(Indirect(), byte_width_); - } else { - return Vector::EmptyVector(); - } - } - - TypedVector AsTypedVector() const { - if (IsTypedVector()) { - auto tv = - TypedVector(Indirect(), byte_width_, ToTypedVectorElementType(type_)); - if (tv.type_ == FBT_STRING) { - // These can't be accessed as strings, since we don't know the bit-width - // of the size field, see the declaration of - // FBT_VECTOR_STRING_DEPRECATED above for details. - // We change the type here to be keys, which are a subtype of strings, - // and will ignore the size field. This will truncate strings with - // embedded nulls. - tv.type_ = FBT_KEY; - } - return tv; - } else { - return TypedVector::EmptyTypedVector(); - } - } - - FixedTypedVector AsFixedTypedVector() const { - if (IsFixedTypedVector()) { - uint8_t len = 0; - auto vtype = ToFixedTypedVectorElementType(type_, &len); - return FixedTypedVector(Indirect(), byte_width_, vtype, len); - } else { - return FixedTypedVector::EmptyFixedTypedVector(); - } - } - - Map AsMap() const { - if (type_ == FBT_MAP) { - return Map(Indirect(), byte_width_); - } else { - return Map::EmptyMap(); - } - } - - template<typename T> T As() const; - - // Experimental: Mutation functions. - // These allow scalars in an already created buffer to be updated in-place. - // Since by default scalars are stored in the smallest possible space, - // the new value may not fit, in which case these functions return false. - // To avoid this, you can construct the values you intend to mutate using - // Builder::ForceMinimumBitWidth. - bool MutateInt(int64_t i) { - if (type_ == FBT_INT) { - return Mutate(data_, i, parent_width_, WidthI(i)); - } else if (type_ == FBT_INDIRECT_INT) { - return Mutate(Indirect(), i, byte_width_, WidthI(i)); - } else if (type_ == FBT_UINT) { - auto u = static_cast<uint64_t>(i); - return Mutate(data_, u, parent_width_, WidthU(u)); - } else if (type_ == FBT_INDIRECT_UINT) { - auto u = static_cast<uint64_t>(i); - return Mutate(Indirect(), u, byte_width_, WidthU(u)); - } else { - return false; - } - } - - bool MutateBool(bool b) { - return type_ == FBT_BOOL && Mutate(data_, b, parent_width_, BIT_WIDTH_8); - } - - bool MutateUInt(uint64_t u) { - if (type_ == FBT_UINT) { - return Mutate(data_, u, parent_width_, WidthU(u)); - } else if (type_ == FBT_INDIRECT_UINT) { - return Mutate(Indirect(), u, byte_width_, WidthU(u)); - } else if (type_ == FBT_INT) { - auto i = static_cast<int64_t>(u); - return Mutate(data_, i, parent_width_, WidthI(i)); - } else if (type_ == FBT_INDIRECT_INT) { - auto i = static_cast<int64_t>(u); - return Mutate(Indirect(), i, byte_width_, WidthI(i)); - } else { - return false; - } - } - - bool MutateFloat(float f) { - if (type_ == FBT_FLOAT) { - return MutateF(data_, f, parent_width_, BIT_WIDTH_32); - } else if (type_ == FBT_INDIRECT_FLOAT) { - return MutateF(Indirect(), f, byte_width_, BIT_WIDTH_32); - } else { - return false; - } - } - - bool MutateFloat(double d) { - if (type_ == FBT_FLOAT) { - return MutateF(data_, d, parent_width_, WidthF(d)); - } else if (type_ == FBT_INDIRECT_FLOAT) { - return MutateF(Indirect(), d, byte_width_, WidthF(d)); - } else { - return false; - } - } - - bool MutateString(const char *str, size_t len) { - auto s = AsString(); - if (s.IsTheEmptyString()) return false; - // This is very strict, could allow shorter strings, but that creates - // garbage. - if (s.length() != len) return false; - memcpy(const_cast<char *>(s.c_str()), str, len); - return true; - } - bool MutateString(const char *str) { return MutateString(str, strlen(str)); } - bool MutateString(const std::string &str) { - return MutateString(str.data(), str.length()); - } - - private: - const uint8_t *Indirect() const { - return flexbuffers::Indirect(data_, parent_width_); - } - - template<typename T> - bool Mutate(const uint8_t *dest, T t, size_t byte_width, - BitWidth value_width) { - auto fits = static_cast<size_t>(static_cast<size_t>(1U) << value_width) <= - byte_width; - if (fits) { - t = flatbuffers::EndianScalar(t); - memcpy(const_cast<uint8_t *>(dest), &t, byte_width); - } - return fits; - } - - template<typename T> - bool MutateF(const uint8_t *dest, T t, size_t byte_width, - BitWidth value_width) { - if (byte_width == sizeof(double)) - return Mutate(dest, static_cast<double>(t), byte_width, value_width); - if (byte_width == sizeof(float)) - return Mutate(dest, static_cast<float>(t), byte_width, value_width); - FLATBUFFERS_ASSERT(false); - return false; - } - - const uint8_t *data_; - uint8_t parent_width_; - uint8_t byte_width_; - Type type_; -}; - -// Template specialization for As(). -template<> inline bool Reference::As<bool>() const { return AsBool(); } - -template<> inline int8_t Reference::As<int8_t>() const { return AsInt8(); } -template<> inline int16_t Reference::As<int16_t>() const { return AsInt16(); } -template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); } -template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); } - -template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); } -template<> inline uint16_t Reference::As<uint16_t>() const { - return AsUInt16(); -} -template<> inline uint32_t Reference::As<uint32_t>() const { - return AsUInt32(); -} -template<> inline uint64_t Reference::As<uint64_t>() const { - return AsUInt64(); -} - -template<> inline double Reference::As<double>() const { return AsDouble(); } -template<> inline float Reference::As<float>() const { return AsFloat(); } - -template<> inline String Reference::As<String>() const { return AsString(); } -template<> inline std::string Reference::As<std::string>() const { - return AsString().str(); -} - -template<> inline Blob Reference::As<Blob>() const { return AsBlob(); } -template<> inline Vector Reference::As<Vector>() const { return AsVector(); } -template<> inline TypedVector Reference::As<TypedVector>() const { - return AsTypedVector(); -} -template<> inline FixedTypedVector Reference::As<FixedTypedVector>() const { - return AsFixedTypedVector(); -} -template<> inline Map Reference::As<Map>() const { return AsMap(); } - -inline uint8_t PackedType(BitWidth bit_width, Type type) { - return static_cast<uint8_t>(bit_width | (type << 2)); -} - -inline uint8_t NullPackedType() { return PackedType(BIT_WIDTH_8, FBT_NULL); } - -// Vector accessors. -// Note: if you try to access outside of bounds, you get a Null value back -// instead. Normally this would be an assert, but since this is "dynamically -// typed" data, you may not want that (someone sends you a 2d vector and you -// wanted 3d). -// The Null converts seamlessly into a default value for any other type. -// TODO(wvo): Could introduce an #ifdef that makes this into an assert? -inline Reference Vector::operator[](size_t i) const { - auto len = size(); - if (i >= len) return Reference(nullptr, 1, NullPackedType()); - auto packed_type = (data_ + len * byte_width_)[i]; - auto elem = data_ + i * byte_width_; - return Reference(elem, byte_width_, packed_type); -} - -inline Reference TypedVector::operator[](size_t i) const { - auto len = size(); - if (i >= len) return Reference(nullptr, 1, NullPackedType()); - auto elem = data_ + i * byte_width_; - return Reference(elem, byte_width_, 1, type_); -} - -inline Reference FixedTypedVector::operator[](size_t i) const { - if (i >= len_) return Reference(nullptr, 1, NullPackedType()); - auto elem = data_ + i * byte_width_; - return Reference(elem, byte_width_, 1, type_); -} - -template<typename T> int KeyCompare(const void *key, const void *elem) { - auto str_elem = reinterpret_cast<const char *>( - Indirect<T>(reinterpret_cast<const uint8_t *>(elem))); - auto skey = reinterpret_cast<const char *>(key); - return strcmp(skey, str_elem); -} - -inline Reference Map::operator[](const char *key) const { - auto keys = Keys(); - // We can't pass keys.byte_width_ to the comparison function, so we have - // to pick the right one ahead of time. - int (*comp)(const void *, const void *) = nullptr; - switch (keys.byte_width_) { - case 1: comp = KeyCompare<uint8_t>; break; - case 2: comp = KeyCompare<uint16_t>; break; - case 4: comp = KeyCompare<uint32_t>; break; - case 8: comp = KeyCompare<uint64_t>; break; - } - auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp); - if (!res) return Reference(nullptr, 1, NullPackedType()); - auto i = (reinterpret_cast<uint8_t *>(res) - keys.data_) / keys.byte_width_; - return (*static_cast<const Vector *>(this))[i]; -} - -inline Reference Map::operator[](const std::string &key) const { - return (*this)[key.c_str()]; -} - -inline Reference GetRoot(const uint8_t *buffer, size_t size) { - // See Finish() below for the serialization counterpart of this. - // The root starts at the end of the buffer, so we parse backwards from there. - auto end = buffer + size; - auto byte_width = *--end; - auto packed_type = *--end; - end -= byte_width; // The root data item. - return Reference(end, byte_width, packed_type); -} - -inline Reference GetRoot(const std::vector<uint8_t> &buffer) { - return GetRoot(flatbuffers::vector_data(buffer), buffer.size()); -} - -// Flags that configure how the Builder behaves. -// The "Share" flags determine if the Builder automatically tries to pool -// this type. Pooling can reduce the size of serialized data if there are -// multiple maps of the same kind, at the expense of slightly slower -// serialization (the cost of lookups) and more memory use (std::set). -// By default this is on for keys, but off for strings. -// Turn keys off if you have e.g. only one map. -// Turn strings on if you expect many non-unique string values. -// Additionally, sharing key vectors can save space if you have maps with -// identical field populations. -enum BuilderFlag { - BUILDER_FLAG_NONE = 0, - BUILDER_FLAG_SHARE_KEYS = 1, - BUILDER_FLAG_SHARE_STRINGS = 2, - BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3, - BUILDER_FLAG_SHARE_KEY_VECTORS = 4, - BUILDER_FLAG_SHARE_ALL = 7, -}; - -class Builder FLATBUFFERS_FINAL_CLASS { - public: - Builder(size_t initial_size = 256, - BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS) - : buf_(initial_size), - finished_(false), - has_duplicate_keys_(false), - flags_(flags), - force_min_bit_width_(BIT_WIDTH_8), - key_pool(KeyOffsetCompare(buf_)), - string_pool(StringOffsetCompare(buf_)) { - buf_.clear(); - } - -#ifdef FLATBUFFERS_DEFAULT_DECLARATION - Builder(Builder &&) = default; - Builder &operator=(Builder &&) = default; -#endif - - /// @brief Get the serialized buffer (after you call `Finish()`). - /// @return Returns a vector owned by this class. - const std::vector<uint8_t> &GetBuffer() const { - Finished(); - return buf_; - } - - // Size of the buffer. Does not include unfinished values. - size_t GetSize() const { return buf_.size(); } - - // Reset all state so we can re-use the buffer. - void Clear() { - buf_.clear(); - stack_.clear(); - finished_ = false; - // flags_ remains as-is; - force_min_bit_width_ = BIT_WIDTH_8; - key_pool.clear(); - string_pool.clear(); - } - - // All value constructing functions below have two versions: one that - // takes a key (for placement inside a map) and one that doesn't (for inside - // vectors and elsewhere). - - void Null() { stack_.push_back(Value()); } - void Null(const char *key) { - Key(key); - Null(); - } - - void Int(int64_t i) { stack_.push_back(Value(i, FBT_INT, WidthI(i))); } - void Int(const char *key, int64_t i) { - Key(key); - Int(i); - } - - void UInt(uint64_t u) { stack_.push_back(Value(u, FBT_UINT, WidthU(u))); } - void UInt(const char *key, uint64_t u) { - Key(key); - UInt(u); - } - - void Float(float f) { stack_.push_back(Value(f)); } - void Float(const char *key, float f) { - Key(key); - Float(f); - } - - void Double(double f) { stack_.push_back(Value(f)); } - void Double(const char *key, double d) { - Key(key); - Double(d); - } - - void Bool(bool b) { stack_.push_back(Value(b)); } - void Bool(const char *key, bool b) { - Key(key); - Bool(b); - } - - void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); } - void IndirectInt(const char *key, int64_t i) { - Key(key); - IndirectInt(i); - } - - void IndirectUInt(uint64_t u) { - PushIndirect(u, FBT_INDIRECT_UINT, WidthU(u)); - } - void IndirectUInt(const char *key, uint64_t u) { - Key(key); - IndirectUInt(u); - } - - void IndirectFloat(float f) { - PushIndirect(f, FBT_INDIRECT_FLOAT, BIT_WIDTH_32); - } - void IndirectFloat(const char *key, float f) { - Key(key); - IndirectFloat(f); - } - - void IndirectDouble(double f) { - PushIndirect(f, FBT_INDIRECT_FLOAT, WidthF(f)); - } - void IndirectDouble(const char *key, double d) { - Key(key); - IndirectDouble(d); - } - - size_t Key(const char *str, size_t len) { - auto sloc = buf_.size(); - WriteBytes(str, len + 1); - if (flags_ & BUILDER_FLAG_SHARE_KEYS) { - auto it = key_pool.find(sloc); - if (it != key_pool.end()) { - // Already in the buffer. Remove key we just serialized, and use - // existing offset instead. - buf_.resize(sloc); - sloc = *it; - } else { - key_pool.insert(sloc); - } - } - stack_.push_back(Value(static_cast<uint64_t>(sloc), FBT_KEY, BIT_WIDTH_8)); - return sloc; - } - - size_t Key(const char *str) { return Key(str, strlen(str)); } - size_t Key(const std::string &str) { return Key(str.c_str(), str.size()); } - - size_t String(const char *str, size_t len) { - auto reset_to = buf_.size(); - auto sloc = CreateBlob(str, len, 1, FBT_STRING); - if (flags_ & BUILDER_FLAG_SHARE_STRINGS) { - StringOffset so(sloc, len); - auto it = string_pool.find(so); - if (it != string_pool.end()) { - // Already in the buffer. Remove string we just serialized, and use - // existing offset instead. - buf_.resize(reset_to); - sloc = it->first; - stack_.back().u_ = sloc; - } else { - string_pool.insert(so); - } - } - return sloc; - } - size_t String(const char *str) { return String(str, strlen(str)); } - size_t String(const std::string &str) { - return String(str.c_str(), str.size()); - } - void String(const flexbuffers::String &str) { - String(str.c_str(), str.length()); - } - - void String(const char *key, const char *str) { - Key(key); - String(str); - } - void String(const char *key, const std::string &str) { - Key(key); - String(str); - } - void String(const char *key, const flexbuffers::String &str) { - Key(key); - String(str); - } - - size_t Blob(const void *data, size_t len) { - return CreateBlob(data, len, 0, FBT_BLOB); - } - size_t Blob(const std::vector<uint8_t> &v) { - return CreateBlob(flatbuffers::vector_data(v), v.size(), 0, FBT_BLOB); - } - - // TODO(wvo): support all the FlexBuffer types (like flexbuffers::String), - // e.g. Vector etc. Also in overloaded versions. - // Also some FlatBuffers types? - - size_t StartVector() { return stack_.size(); } - size_t StartVector(const char *key) { - Key(key); - return stack_.size(); - } - size_t StartMap() { return stack_.size(); } - size_t StartMap(const char *key) { - Key(key); - return stack_.size(); - } - - // TODO(wvo): allow this to specify an aligment greater than the natural - // alignment. - size_t EndVector(size_t start, bool typed, bool fixed) { - auto vec = CreateVector(start, stack_.size() - start, 1, typed, fixed); - // Remove temp elements and return vector. - stack_.resize(start); - stack_.push_back(vec); - return static_cast<size_t>(vec.u_); - } - - size_t EndMap(size_t start) { - // We should have interleaved keys and values on the stack. - // Make sure it is an even number: - auto len = stack_.size() - start; - FLATBUFFERS_ASSERT(!(len & 1)); - len /= 2; - // Make sure keys are all strings: - for (auto key = start; key < stack_.size(); key += 2) { - FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY); - } - // Now sort values, so later we can do a binary search lookup. - // We want to sort 2 array elements at a time. - struct TwoValue { - Value key; - Value val; - }; - // TODO(wvo): strict aliasing? - // TODO(wvo): allow the caller to indicate the data is already sorted - // for maximum efficiency? With an assert to check sortedness to make sure - // we're not breaking binary search. - // Or, we can track if the map is sorted as keys are added which would be - // be quite cheap (cheaper than checking it here), so we can skip this - // step automatically when appliccable, and encourage people to write in - // sorted fashion. - // std::sort is typically already a lot faster on sorted data though. - auto dict = - reinterpret_cast<TwoValue *>(flatbuffers::vector_data(stack_) + start); - std::sort(dict, dict + len, - [&](const TwoValue &a, const TwoValue &b) -> bool { - auto as = reinterpret_cast<const char *>( - flatbuffers::vector_data(buf_) + a.key.u_); - auto bs = reinterpret_cast<const char *>( - flatbuffers::vector_data(buf_) + b.key.u_); - auto comp = strcmp(as, bs); - // We want to disallow duplicate keys, since this results in a - // map where values cannot be found. - // But we can't assert here (since we don't want to fail on - // random JSON input) or have an error mechanism. - // Instead, we set has_duplicate_keys_ in the builder to - // signal this. - // TODO: Have to check for pointer equality, as some sort - // implementation apparently call this function with the same - // element?? Why? - if (!comp && &a != &b) has_duplicate_keys_ = true; - return comp < 0; - }); - // First create a vector out of all keys. - // TODO(wvo): if kBuilderFlagShareKeyVectors is true, see if we can share - // the first vector. - auto keys = CreateVector(start, len, 2, true, false); - auto vec = CreateVector(start + 1, len, 2, false, false, &keys); - // Remove temp elements and return map. - stack_.resize(start); - stack_.push_back(vec); - return static_cast<size_t>(vec.u_); - } - - // Call this after EndMap to see if the map had any duplicate keys. - // Any map with such keys won't be able to retrieve all values. - bool HasDuplicateKeys() const { return has_duplicate_keys_; } - - template<typename F> size_t Vector(F f) { - auto start = StartVector(); - f(); - return EndVector(start, false, false); - } - template<typename F, typename T> size_t Vector(F f, T &state) { - auto start = StartVector(); - f(state); - return EndVector(start, false, false); - } - template<typename F> size_t Vector(const char *key, F f) { - auto start = StartVector(key); - f(); - return EndVector(start, false, false); - } - template<typename F, typename T> - size_t Vector(const char *key, F f, T &state) { - auto start = StartVector(key); - f(state); - return EndVector(start, false, false); - } - - template<typename T> void Vector(const T *elems, size_t len) { - if (flatbuffers::is_scalar<T>::value) { - // This path should be a lot quicker and use less space. - ScalarVector(elems, len, false); - } else { - auto start = StartVector(); - for (size_t i = 0; i < len; i++) Add(elems[i]); - EndVector(start, false, false); - } - } - template<typename T> - void Vector(const char *key, const T *elems, size_t len) { - Key(key); - Vector(elems, len); - } - template<typename T> void Vector(const std::vector<T> &vec) { - Vector(flatbuffers::vector_data(vec), vec.size()); - } - - template<typename F> size_t TypedVector(F f) { - auto start = StartVector(); - f(); - return EndVector(start, true, false); - } - template<typename F, typename T> size_t TypedVector(F f, T &state) { - auto start = StartVector(); - f(state); - return EndVector(start, true, false); - } - template<typename F> size_t TypedVector(const char *key, F f) { - auto start = StartVector(key); - f(); - return EndVector(start, true, false); - } - template<typename F, typename T> - size_t TypedVector(const char *key, F f, T &state) { - auto start = StartVector(key); - f(state); - return EndVector(start, true, false); - } - - template<typename T> size_t FixedTypedVector(const T *elems, size_t len) { - // We only support a few fixed vector lengths. Anything bigger use a - // regular typed vector. - FLATBUFFERS_ASSERT(len >= 2 && len <= 4); - // And only scalar values. - static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types"); - return ScalarVector(elems, len, true); - } - - template<typename T> - size_t FixedTypedVector(const char *key, const T *elems, size_t len) { - Key(key); - return FixedTypedVector(elems, len); - } - - template<typename F> size_t Map(F f) { - auto start = StartMap(); - f(); - return EndMap(start); - } - template<typename F, typename T> size_t Map(F f, T &state) { - auto start = StartMap(); - f(state); - return EndMap(start); - } - template<typename F> size_t Map(const char *key, F f) { - auto start = StartMap(key); - f(); - return EndMap(start); - } - template<typename F, typename T> size_t Map(const char *key, F f, T &state) { - auto start = StartMap(key); - f(state); - return EndMap(start); - } - template<typename T> void Map(const std::map<std::string, T> &map) { - auto start = StartMap(); - for (auto it = map.begin(); it != map.end(); ++it) - Add(it->first.c_str(), it->second); - EndMap(start); - } - - // If you wish to share a value explicitly (a value not shared automatically - // through one of the BUILDER_FLAG_SHARE_* flags) you can do so with these - // functions. Or if you wish to turn those flags off for performance reasons - // and still do some explicit sharing. For example: - // builder.IndirectDouble(M_PI); - // auto id = builder.LastValue(); // Remember where we stored it. - // .. more code goes here .. - // builder.ReuseValue(id); // Refers to same double by offset. - // LastValue works regardless of whether the value has a key or not. - // Works on any data type. - struct Value; - Value LastValue() { return stack_.back(); } - void ReuseValue(Value v) { stack_.push_back(v); } - void ReuseValue(const char *key, Value v) { - Key(key); - ReuseValue(v); - } - - // Overloaded Add that tries to call the correct function above. - void Add(int8_t i) { Int(i); } - void Add(int16_t i) { Int(i); } - void Add(int32_t i) { Int(i); } - void Add(int64_t i) { Int(i); } - void Add(uint8_t u) { UInt(u); } - void Add(uint16_t u) { UInt(u); } - void Add(uint32_t u) { UInt(u); } - void Add(uint64_t u) { UInt(u); } - void Add(float f) { Float(f); } - void Add(double d) { Double(d); } - void Add(bool b) { Bool(b); } - void Add(const char *str) { String(str); } - void Add(const std::string &str) { String(str); } - void Add(const flexbuffers::String &str) { String(str); } - - template<typename T> void Add(const std::vector<T> &vec) { Vector(vec); } - - template<typename T> void Add(const char *key, const T &t) { - Key(key); - Add(t); - } - - template<typename T> void Add(const std::map<std::string, T> &map) { - Map(map); - } - - template<typename T> void operator+=(const T &t) { Add(t); } - - // This function is useful in combination with the Mutate* functions above. - // It forces elements of vectors and maps to have a minimum size, such that - // they can later be updated without failing. - // Call with no arguments to reset. - void ForceMinimumBitWidth(BitWidth bw = BIT_WIDTH_8) { - force_min_bit_width_ = bw; - } - - void Finish() { - // If you hit this assert, you likely have objects that were never included - // in a parent. You need to have exactly one root to finish a buffer. - // Check your Start/End calls are matched, and all objects are inside - // some other object. - FLATBUFFERS_ASSERT(stack_.size() == 1); - - // Write root value. - auto byte_width = Align(stack_[0].ElemWidth(buf_.size(), 0)); - WriteAny(stack_[0], byte_width); - // Write root type. - Write(stack_[0].StoredPackedType(), 1); - // Write root size. Normally determined by parent, but root has no parent :) - Write(byte_width, 1); - - finished_ = true; - } - - private: - void Finished() const { - // If you get this assert, you're attempting to get access a buffer - // which hasn't been finished yet. Be sure to call - // Builder::Finish with your root object. - FLATBUFFERS_ASSERT(finished_); - } - - // Align to prepare for writing a scalar with a certain size. - uint8_t Align(BitWidth alignment) { - auto byte_width = 1U << alignment; - buf_.insert(buf_.end(), flatbuffers::PaddingBytes(buf_.size(), byte_width), - 0); - return static_cast<uint8_t>(byte_width); - } - - void WriteBytes(const void *val, size_t size) { - buf_.insert(buf_.end(), reinterpret_cast<const uint8_t *>(val), - reinterpret_cast<const uint8_t *>(val) + size); - } - - template<typename T> void Write(T val, size_t byte_width) { - FLATBUFFERS_ASSERT(sizeof(T) >= byte_width); - val = flatbuffers::EndianScalar(val); - WriteBytes(&val, byte_width); - } - - void WriteDouble(double f, uint8_t byte_width) { - switch (byte_width) { - case 8: Write(f, byte_width); break; - case 4: Write(static_cast<float>(f), byte_width); break; - // case 2: Write(static_cast<half>(f), byte_width); break; - // case 1: Write(static_cast<quarter>(f), byte_width); break; - default: FLATBUFFERS_ASSERT(0); - } - } - - void WriteOffset(uint64_t o, uint8_t byte_width) { - auto reloff = buf_.size() - o; - FLATBUFFERS_ASSERT(byte_width == 8 || reloff < 1ULL << (byte_width * 8)); - Write(reloff, byte_width); - } - - template<typename T> void PushIndirect(T val, Type type, BitWidth bit_width) { - auto byte_width = Align(bit_width); - auto iloc = buf_.size(); - Write(val, byte_width); - stack_.push_back(Value(static_cast<uint64_t>(iloc), type, bit_width)); - } - - static BitWidth WidthB(size_t byte_width) { - switch (byte_width) { - case 1: return BIT_WIDTH_8; - case 2: return BIT_WIDTH_16; - case 4: return BIT_WIDTH_32; - case 8: return BIT_WIDTH_64; - default: FLATBUFFERS_ASSERT(false); return BIT_WIDTH_64; - } - } - - template<typename T> static Type GetScalarType() { - static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types"); - return flatbuffers::is_floating_point<T>::value - ? FBT_FLOAT - : flatbuffers::is_same<T, bool>::value - ? FBT_BOOL - : (flatbuffers::is_unsigned<T>::value ? FBT_UINT - : FBT_INT); - } - - public: - // This was really intended to be private, except for LastValue/ReuseValue. - struct Value { - union { - int64_t i_; - uint64_t u_; - double f_; - }; - - Type type_; - - // For scalars: of itself, for vector: of its elements, for string: length. - BitWidth min_bit_width_; - - Value() : i_(0), type_(FBT_NULL), min_bit_width_(BIT_WIDTH_8) {} - - Value(bool b) - : u_(static_cast<uint64_t>(b)), - type_(FBT_BOOL), - min_bit_width_(BIT_WIDTH_8) {} - - Value(int64_t i, Type t, BitWidth bw) - : i_(i), type_(t), min_bit_width_(bw) {} - Value(uint64_t u, Type t, BitWidth bw) - : u_(u), type_(t), min_bit_width_(bw) {} - - Value(float f) - : f_(static_cast<double>(f)), - type_(FBT_FLOAT), - min_bit_width_(BIT_WIDTH_32) {} - Value(double f) : f_(f), type_(FBT_FLOAT), min_bit_width_(WidthF(f)) {} - - uint8_t StoredPackedType(BitWidth parent_bit_width_ = BIT_WIDTH_8) const { - return PackedType(StoredWidth(parent_bit_width_), type_); - } - - BitWidth ElemWidth(size_t buf_size, size_t elem_index) const { - if (IsInline(type_)) { - return min_bit_width_; - } else { - // We have an absolute offset, but want to store a relative offset - // elem_index elements beyond the current buffer end. Since whether - // the relative offset fits in a certain byte_width depends on - // the size of the elements before it (and their alignment), we have - // to test for each size in turn. - for (size_t byte_width = 1; - byte_width <= sizeof(flatbuffers::largest_scalar_t); - byte_width *= 2) { - // Where are we going to write this offset? - auto offset_loc = buf_size + - flatbuffers::PaddingBytes(buf_size, byte_width) + - elem_index * byte_width; - // Compute relative offset. - auto offset = offset_loc - u_; - // Does it fit? - auto bit_width = WidthU(offset); - if (static_cast<size_t>(static_cast<size_t>(1U) << bit_width) == - byte_width) - return bit_width; - } - FLATBUFFERS_ASSERT(false); // Must match one of the sizes above. - return BIT_WIDTH_64; - } - } - - BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const { - if (IsInline(type_)) { - return (std::max)(min_bit_width_, parent_bit_width_); - } else { - return min_bit_width_; - } - } - }; - - private: - void WriteAny(const Value &val, uint8_t byte_width) { - switch (val.type_) { - case FBT_NULL: - case FBT_INT: Write(val.i_, byte_width); break; - case FBT_BOOL: - case FBT_UINT: Write(val.u_, byte_width); break; - case FBT_FLOAT: WriteDouble(val.f_, byte_width); break; - default: WriteOffset(val.u_, byte_width); break; - } - } - - size_t CreateBlob(const void *data, size_t len, size_t trailing, Type type) { - auto bit_width = WidthU(len); - auto byte_width = Align(bit_width); - Write<uint64_t>(len, byte_width); - auto sloc = buf_.size(); - WriteBytes(data, len + trailing); - stack_.push_back(Value(static_cast<uint64_t>(sloc), type, bit_width)); - return sloc; - } - - template<typename T> - size_t ScalarVector(const T *elems, size_t len, bool fixed) { - auto vector_type = GetScalarType<T>(); - auto byte_width = sizeof(T); - auto bit_width = WidthB(byte_width); - // If you get this assert, you're trying to write a vector with a size - // field that is bigger than the scalars you're trying to write (e.g. a - // byte vector > 255 elements). For such types, write a "blob" instead. - // TODO: instead of asserting, could write vector with larger elements - // instead, though that would be wasteful. - FLATBUFFERS_ASSERT(WidthU(len) <= bit_width); - Align(bit_width); - if (!fixed) Write<uint64_t>(len, byte_width); - auto vloc = buf_.size(); - for (size_t i = 0; i < len; i++) Write(elems[i], byte_width); - stack_.push_back(Value(static_cast<uint64_t>(vloc), - ToTypedVector(vector_type, fixed ? len : 0), - bit_width)); - return vloc; - } - - Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed, - bool fixed, const Value *keys = nullptr) { - FLATBUFFERS_ASSERT( - !fixed || - typed); // typed=false, fixed=true combination is not supported. - // Figure out smallest bit width we can store this vector with. - auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len)); - auto prefix_elems = 1; - if (keys) { - // If this vector is part of a map, we will pre-fix an offset to the keys - // to this vector. - bit_width = (std::max)(bit_width, keys->ElemWidth(buf_.size(), 0)); - prefix_elems += 2; - } - Type vector_type = FBT_KEY; - // Check bit widths and types for all elements. - for (size_t i = start; i < stack_.size(); i += step) { - auto elem_width = - stack_[i].ElemWidth(buf_.size(), i - start + prefix_elems); - bit_width = (std::max)(bit_width, elem_width); - if (typed) { - if (i == start) { - vector_type = stack_[i].type_; - } else { - // If you get this assert, you are writing a typed vector with - // elements that are not all the same type. - FLATBUFFERS_ASSERT(vector_type == stack_[i].type_); - } - } - } - // If you get this assert, your fixed types are not one of: - // Int / UInt / Float / Key. - FLATBUFFERS_ASSERT(!fixed || IsTypedVectorElementType(vector_type)); - auto byte_width = Align(bit_width); - // Write vector. First the keys width/offset if available, and size. - if (keys) { - WriteOffset(keys->u_, byte_width); - Write<uint64_t>(1ULL << keys->min_bit_width_, byte_width); - } - if (!fixed) Write<uint64_t>(vec_len, byte_width); - // Then the actual data. - auto vloc = buf_.size(); - for (size_t i = start; i < stack_.size(); i += step) { - WriteAny(stack_[i], byte_width); - } - // Then the types. - if (!typed) { - for (size_t i = start; i < stack_.size(); i += step) { - buf_.push_back(stack_[i].StoredPackedType(bit_width)); - } - } - return Value(static_cast<uint64_t>(vloc), - keys ? FBT_MAP - : (typed ? ToTypedVector(vector_type, fixed ? vec_len : 0) - : FBT_VECTOR), - bit_width); - } - - // You shouldn't really be copying instances of this class. - Builder(const Builder &); - Builder &operator=(const Builder &); - - std::vector<uint8_t> buf_; - std::vector<Value> stack_; - - bool finished_; - bool has_duplicate_keys_; - - BuilderFlag flags_; - - BitWidth force_min_bit_width_; - - struct KeyOffsetCompare { - explicit KeyOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {} - bool operator()(size_t a, size_t b) const { - auto stra = - reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + a); - auto strb = - reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + b); - return strcmp(stra, strb) < 0; - } - const std::vector<uint8_t> *buf_; - }; - - typedef std::pair<size_t, size_t> StringOffset; - struct StringOffsetCompare { - explicit StringOffsetCompare(const std::vector<uint8_t> &buf) - : buf_(&buf) {} - bool operator()(const StringOffset &a, const StringOffset &b) const { - auto stra = reinterpret_cast<const char *>( - flatbuffers::vector_data(*buf_) + a.first); - auto strb = reinterpret_cast<const char *>( - flatbuffers::vector_data(*buf_) + b.first); - return strncmp(stra, strb, (std::min)(a.second, b.second) + 1) < 0; - } - const std::vector<uint8_t> *buf_; - }; - - typedef std::set<size_t, KeyOffsetCompare> KeyOffsetMap; - typedef std::set<StringOffset, StringOffsetCompare> StringOffsetMap; - - KeyOffsetMap key_pool; - StringOffsetMap string_pool; -}; - -} // namespace flexbuffers - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - -#endif // FLATBUFFERS_FLEXBUFFERS_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/hash.h b/contrib/libs/flatbuffers/include/flatbuffers/hash.h deleted file mode 100644 index 52cc628cdf..0000000000 --- a/contrib/libs/flatbuffers/include/flatbuffers/hash.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2015 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_HASH_H_ -#define FLATBUFFERS_HASH_H_ - -#include <cstdint> -#include <cstring> - -#include "flatbuffers.h" - -namespace flatbuffers { - -template<typename T> struct FnvTraits { - static const T kFnvPrime; - static const T kOffsetBasis; -}; - -template<> struct FnvTraits<uint32_t> { - static const uint32_t kFnvPrime = 0x01000193; - static const uint32_t kOffsetBasis = 0x811C9DC5; -}; - -template<> struct FnvTraits<uint64_t> { - static const uint64_t kFnvPrime = 0x00000100000001b3ULL; - static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL; -}; - -template<typename T> T HashFnv1(const char *input) { - T hash = FnvTraits<T>::kOffsetBasis; - for (const char *c = input; *c; ++c) { - hash *= FnvTraits<T>::kFnvPrime; - hash ^= static_cast<unsigned char>(*c); - } - return hash; -} - -template<typename T> T HashFnv1a(const char *input) { - T hash = FnvTraits<T>::kOffsetBasis; - for (const char *c = input; *c; ++c) { - hash ^= static_cast<unsigned char>(*c); - hash *= FnvTraits<T>::kFnvPrime; - } - return hash; -} - -template<> inline uint16_t HashFnv1<uint16_t>(const char *input) { - uint32_t hash = HashFnv1<uint32_t>(input); - return (hash >> 16) ^ (hash & 0xffff); -} - -template<> inline uint16_t HashFnv1a<uint16_t>(const char *input) { - uint32_t hash = HashFnv1a<uint32_t>(input); - return (hash >> 16) ^ (hash & 0xffff); -} - -template<typename T> struct NamedHashFunction { - const char *name; - - typedef T (*HashFunction)(const char *); - HashFunction function; -}; - -const NamedHashFunction<uint16_t> kHashFunctions16[] = { - { "fnv1_16", HashFnv1<uint16_t> }, - { "fnv1a_16", HashFnv1a<uint16_t> }, -}; - -const NamedHashFunction<uint32_t> kHashFunctions32[] = { - { "fnv1_32", HashFnv1<uint32_t> }, - { "fnv1a_32", HashFnv1a<uint32_t> }, -}; - -const NamedHashFunction<uint64_t> kHashFunctions64[] = { - { "fnv1_64", HashFnv1<uint64_t> }, - { "fnv1a_64", HashFnv1a<uint64_t> }, -}; - -inline NamedHashFunction<uint16_t>::HashFunction FindHashFunction16( - const char *name) { - std::size_t size = sizeof(kHashFunctions16) / sizeof(kHashFunctions16[0]); - for (std::size_t i = 0; i < size; ++i) { - if (std::strcmp(name, kHashFunctions16[i].name) == 0) { - return kHashFunctions16[i].function; - } - } - return nullptr; -} - -inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32( - const char *name) { - std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]); - for (std::size_t i = 0; i < size; ++i) { - if (std::strcmp(name, kHashFunctions32[i].name) == 0) { - return kHashFunctions32[i].function; - } - } - return nullptr; -} - -inline NamedHashFunction<uint64_t>::HashFunction FindHashFunction64( - const char *name) { - std::size_t size = sizeof(kHashFunctions64) / sizeof(kHashFunctions64[0]); - for (std::size_t i = 0; i < size; ++i) { - if (std::strcmp(name, kHashFunctions64[i].name) == 0) { - return kHashFunctions64[i].function; - } - } - return nullptr; -} - -} // namespace flatbuffers - -#endif // FLATBUFFERS_HASH_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/idl.h b/contrib/libs/flatbuffers/include/flatbuffers/idl.h deleted file mode 100644 index a82ff8a694..0000000000 --- a/contrib/libs/flatbuffers/include/flatbuffers/idl.h +++ /dev/null @@ -1,1208 +0,0 @@ -/* - * Copyright 2014 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_IDL_H_ -#define FLATBUFFERS_IDL_H_ - -#include <map> -#include <memory> -#include <stack> - -#include "base.h" -#include "flatbuffers.h" -#include "flexbuffers.h" -#include "hash.h" -#include "reflection.h" - -#if !defined(FLATBUFFERS_CPP98_STL) -# include <functional> -#endif // !defined(FLATBUFFERS_CPP98_STL) - -// This file defines the data types representing a parsed IDL (Interface -// Definition Language) / schema file. - -// Limits maximum depth of nested objects. -// Prevents stack overflow while parse scheme, or json, or flexbuffer. -#if !defined(FLATBUFFERS_MAX_PARSING_DEPTH) -# define FLATBUFFERS_MAX_PARSING_DEPTH 64 -#endif - -namespace flatbuffers { - -// The order of these matters for Is*() functions below. -// Additionally, Parser::ParseType assumes bool..string is a contiguous range -// of type tokens. -// clang-format off -#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ - TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \ - TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) /* begin scalar/int */ \ - TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool, Boolean, Bool) \ - TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8, Byte, Int8) \ - TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \ - TD(SHORT, "short", int16_t, short, int16, short, int16, i16, Short, Int16) \ - TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16, UShort, UInt16) \ - TD(INT, "int", int32_t, int, int32, int, int32, i32, Int, Int32) \ - TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32, UInt, UInt32) \ - TD(LONG, "long", int64_t, long, int64, long, int64, i64, Long, Int64) \ - TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64, ULong, UInt64) /* end int */ \ - TD(FLOAT, "float", float, float, float32, float, float32, f32, Float, Float32) /* begin float */ \ - TD(DOUBLE, "double", double, double, float64, double, float64, f64, Double, Double) /* end float/scalar */ -#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \ - TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int, Offset<String>) \ - TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>) \ - TD(STRUCT, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>) \ - TD(UNION, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>) -#define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \ - TD(ARRAY, "", int, int, int, int, int, unused, Int, Offset<UOffset>) -// The fields are: -// - enum -// - FlatBuffers schema type. -// - C++ type. -// - Java type. -// - Go type. -// - C# / .Net type. -// - Python type. -// - Rust type. -// - Kotlin type. - -// using these macros, we can now write code dealing with types just once, e.g. - -/* -switch (type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, KTYPE) \ - case BASE_TYPE_ ## ENUM: \ - // do something specific to CTYPE here - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD -} -*/ - -// If not all FLATBUFFERS_GEN_() arguments are necessary for implementation -// of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed). -// In the above example, only CTYPE is used to generate the code, it can be rewritten: - -/* -switch (type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - // do something specific to CTYPE here - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD -} -*/ - -#define FLATBUFFERS_GEN_TYPES(TD) \ - FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ - FLATBUFFERS_GEN_TYPES_POINTER(TD) \ - FLATBUFFERS_GEN_TYPE_ARRAY(TD) - -// Create an enum for all the types above. -#ifdef __GNUC__ -__extension__ // Stop GCC complaining about trailing comma with -Wpendantic. -#endif -enum BaseType { - #define FLATBUFFERS_TD(ENUM, ...) \ - BASE_TYPE_ ## ENUM, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD -}; - -#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \ - "define largest_scalar_t as " #CTYPE); - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) -#undef FLATBUFFERS_TD - -inline bool IsScalar (BaseType t) { return t >= BASE_TYPE_UTYPE && - t <= BASE_TYPE_DOUBLE; } -inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE && - t <= BASE_TYPE_ULONG; } -inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT || - t == BASE_TYPE_DOUBLE; } -inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG || - t == BASE_TYPE_ULONG; } -inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; } -inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE && - t <= BASE_TYPE_UCHAR; } - -inline bool IsUnsigned(BaseType t) { - return (t == BASE_TYPE_UTYPE) || (t == BASE_TYPE_UCHAR) || - (t == BASE_TYPE_USHORT) || (t == BASE_TYPE_UINT) || - (t == BASE_TYPE_ULONG); -} - -// clang-format on - -extern const char *const kTypeNames[]; -extern const char kTypeSizes[]; - -inline size_t SizeOf(BaseType t) { return kTypeSizes[t]; } - -struct StructDef; -struct EnumDef; -class Parser; - -// Represents any type in the IDL, which is a combination of the BaseType -// and additional information for vectors/structs_. -struct Type { - explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr, - EnumDef *_ed = nullptr, uint16_t _fixed_length = 0) - : base_type(_base_type), - element(BASE_TYPE_NONE), - struct_def(_sd), - enum_def(_ed), - fixed_length(_fixed_length) {} - - bool operator==(const Type &o) { - return base_type == o.base_type && element == o.element && - struct_def == o.struct_def && enum_def == o.enum_def; - } - - Type VectorType() const { - return Type(element, struct_def, enum_def, fixed_length); - } - - Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const; - - bool Deserialize(const Parser &parser, const reflection::Type *type); - - BaseType base_type; - BaseType element; // only set if t == BASE_TYPE_VECTOR - StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT - EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE, - // or for an integral type derived from an enum. - uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY -}; - -// Represents a parsed scalar value, it's type, and field offset. -struct Value { - Value() - : constant("0"), - offset(static_cast<voffset_t>(~(static_cast<voffset_t>(0U)))) {} - Type type; - std::string constant; - voffset_t offset; -}; - -// Helper class that retains the original order of a set of identifiers and -// also provides quick lookup. -template<typename T> class SymbolTable { - public: - ~SymbolTable() { - for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; } - } - - bool Add(const std::string &name, T *e) { - vector_emplace_back(&vec, e); - auto it = dict.find(name); - if (it != dict.end()) return true; - dict[name] = e; - return false; - } - - void Move(const std::string &oldname, const std::string &newname) { - auto it = dict.find(oldname); - if (it != dict.end()) { - auto obj = it->second; - dict.erase(it); - dict[newname] = obj; - } else { - FLATBUFFERS_ASSERT(false); - } - } - - T *Lookup(const std::string &name) const { - auto it = dict.find(name); - return it == dict.end() ? nullptr : it->second; - } - - public: - std::map<std::string, T *> dict; // quick lookup - std::vector<T *> vec; // Used to iterate in order of insertion -}; - -// A name space, as set in the schema. -struct Namespace { - Namespace() : from_table(0) {} - - // Given a (potentially unqualified) name, return the "fully qualified" name - // which has a full namespaced descriptor. - // With max_components you can request less than the number of components - // the current namespace has. - std::string GetFullyQualifiedName(const std::string &name, - size_t max_components = 1000) const; - - std::vector<std::string> components; - size_t from_table; // Part of the namespace corresponds to a message/table. -}; - -inline bool operator<(const Namespace &a, const Namespace &b) { - size_t min_size = std::min(a.components.size(), b.components.size()); - for (size_t i = 0; i < min_size; ++i) { - if (a.components[i] != b.components[i]) - return a.components[i] < b.components[i]; - } - return a.components.size() < b.components.size(); -} - -// Base class for all definition types (fields, structs_, enums_). -struct Definition { - Definition() - : generated(false), - defined_namespace(nullptr), - serialized_location(0), - index(-1), - refcount(1) {} - - flatbuffers::Offset< - flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> - SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const; - - bool DeserializeAttributes(Parser &parser, - const Vector<Offset<reflection::KeyValue>> *attrs); - - std::string name; - std::string file; - std::vector<std::string> doc_comment; - SymbolTable<Value> attributes; - bool generated; // did we already output code for this definition? - Namespace *defined_namespace; // Where it was defined. - - // For use with Serialize() - uoffset_t serialized_location; - int index; // Inside the vector it is stored. - int refcount; -}; - -struct FieldDef : public Definition { - FieldDef() - : deprecated(false), - key(false), - shared(false), - native_inline(false), - flexbuffer(false), - presence(kDefault), - nested_flatbuffer(NULL), - padding(0) {} - - Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id, - const Parser &parser) const; - - bool Deserialize(Parser &parser, const reflection::Field *field); - - bool IsScalarOptional() const { - return IsScalar(value.type.base_type) && IsOptional(); - } - bool IsOptional() const { - return presence == kOptional; - } - bool IsRequired() const { - return presence == kRequired; - } - bool IsDefault() const { - return presence == kDefault; - } - - Value value; - bool deprecated; // Field is allowed to be present in old data, but can't be. - // written in new data nor accessed in new code. - bool key; // Field functions as a key for creating sorted vectors. - bool shared; // Field will be using string pooling (i.e. CreateSharedString) - // as default serialization behavior if field is a string. - bool native_inline; // Field will be defined inline (instead of as a pointer) - // for native tables if field is a struct. - bool flexbuffer; // This field contains FlexBuffer data. - - enum Presence { - // Field must always be present. - kRequired, - // Non-presence should be signalled to and controlled by users. - kOptional, - // Non-presence is hidden from users. - // Implementations may omit writing default values. - kDefault, - }; - Presence static MakeFieldPresence(bool optional, bool required) { - FLATBUFFERS_ASSERT(!(required && optional)); - // clang-format off - return required ? FieldDef::kRequired - : optional ? FieldDef::kOptional - : FieldDef::kDefault; - // clang-format on - } - Presence presence; - - StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data. - size_t padding; // Bytes to always pad after this field. -}; - -struct StructDef : public Definition { - StructDef() - : fixed(false), - predecl(true), - sortbysize(true), - has_key(false), - minalign(1), - bytesize(0) {} - - void PadLastField(size_t min_align) { - auto padding = PaddingBytes(bytesize, min_align); - bytesize += padding; - if (fields.vec.size()) fields.vec.back()->padding = padding; - } - - Offset<reflection::Object> Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - - bool Deserialize(Parser &parser, const reflection::Object *object); - - SymbolTable<FieldDef> fields; - - bool fixed; // If it's struct, not a table. - bool predecl; // If it's used before it was defined. - bool sortbysize; // Whether fields come in the declaration or size order. - bool has_key; // It has a key field. - size_t minalign; // What the whole object needs to be aligned to. - size_t bytesize; // Size if fixed. - - flatbuffers::unique_ptr<std::string> original_location; -}; - -struct EnumDef; -struct EnumValBuilder; - -struct EnumVal { - Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - - bool Deserialize(const Parser &parser, const reflection::EnumVal *val); - - uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); } - int64_t GetAsInt64() const { return value; } - bool IsZero() const { return 0 == value; } - bool IsNonZero() const { return !IsZero(); } - - std::string name; - std::vector<std::string> doc_comment; - Type union_type; - - private: - friend EnumDef; - friend EnumValBuilder; - friend bool operator==(const EnumVal &lhs, const EnumVal &rhs); - - EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {} - EnumVal() : value(0) {} - - int64_t value; -}; - -struct EnumDef : public Definition { - EnumDef() : is_union(false), uses_multiple_type_instances(false) {} - - Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - - bool Deserialize(Parser &parser, const reflection::Enum *values); - - template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val); - void SortByValue(); - void RemoveDuplicates(); - - std::string AllFlags() const; - const EnumVal *MinValue() const; - const EnumVal *MaxValue() const; - // Returns the number of integer steps from v1 to v2. - uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const; - // Returns the number of integer steps from Min to Max. - uint64_t Distance() const { return Distance(MinValue(), MaxValue()); } - - EnumVal *ReverseLookup(int64_t enum_idx, - bool skip_union_default = false) const; - EnumVal *FindByValue(const std::string &constant) const; - - std::string ToString(const EnumVal &ev) const { - return IsUInt64() ? NumToString(ev.GetAsUInt64()) - : NumToString(ev.GetAsInt64()); - } - - size_t size() const { return vals.vec.size(); } - - const std::vector<EnumVal *> &Vals() const { return vals.vec; } - - const EnumVal *Lookup(const std::string &enum_name) const { - return vals.Lookup(enum_name); - } - - bool is_union; - // Type is a union which uses type aliases where at least one type is - // available under two different names. - bool uses_multiple_type_instances; - Type underlying_type; - - private: - bool IsUInt64() const { - return (BASE_TYPE_ULONG == underlying_type.base_type); - } - - friend EnumValBuilder; - SymbolTable<EnumVal> vals; -}; - -inline bool IsString(const Type &type) { - return type.base_type == BASE_TYPE_STRING; -} - -inline bool IsStruct(const Type &type) { - return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed; -} - -inline bool IsUnion(const Type &type) { - return type.enum_def != nullptr && type.enum_def->is_union; -} - -inline bool IsVector(const Type &type) { - return type.base_type == BASE_TYPE_VECTOR; -} - -inline bool IsArray(const Type &type) { - return type.base_type == BASE_TYPE_ARRAY; -} - -inline bool IsSeries(const Type &type) { - return IsVector(type) || IsArray(type); -} - -inline bool IsEnum(const Type &type) { - return type.enum_def != nullptr && IsInteger(type.base_type); -} - -inline size_t InlineSize(const Type &type) { - return IsStruct(type) - ? type.struct_def->bytesize - : (IsArray(type) - ? InlineSize(type.VectorType()) * type.fixed_length - : SizeOf(type.base_type)); -} - -inline size_t InlineAlignment(const Type &type) { - if (IsStruct(type)) { - return type.struct_def->minalign; - } else if (IsArray(type)) { - return IsStruct(type.VectorType()) ? type.struct_def->minalign - : SizeOf(type.element); - } else { - return SizeOf(type.base_type); - } -} -inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) { - return lhs.value == rhs.value; -} -inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) { - return !(lhs == rhs); -} - -inline bool EqualByName(const Type &a, const Type &b) { - return a.base_type == b.base_type && a.element == b.element && - (a.struct_def == b.struct_def || - a.struct_def->name == b.struct_def->name) && - (a.enum_def == b.enum_def || a.enum_def->name == b.enum_def->name); -} - -struct RPCCall : public Definition { - Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - - bool Deserialize(Parser &parser, const reflection::RPCCall *call); - - StructDef *request, *response; -}; - -struct ServiceDef : public Definition { - Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - bool Deserialize(Parser &parser, const reflection::Service *service); - - SymbolTable<RPCCall> calls; -}; - -// Container of options that may apply to any of the source/text generators. -struct IDLOptions { - bool gen_jvmstatic; - // Use flexbuffers instead for binary and text generation - bool use_flexbuffers; - bool strict_json; - bool output_default_scalars_in_json; - int indent_step; - bool output_enum_identifiers; - bool prefixed_enums; - bool scoped_enums; - bool include_dependence_headers; - bool mutable_buffer; - bool one_file; - bool proto_mode; - bool proto_oneof_union; - bool generate_all; - bool skip_unexpected_fields_in_json; - bool generate_name_strings; - bool generate_object_based_api; - bool gen_compare; - std::string cpp_object_api_pointer_type; - std::string cpp_object_api_string_type; - bool cpp_object_api_string_flexible_constructor; - bool cpp_direct_copy; - bool gen_nullable; - bool java_checkerframework; - bool gen_generated; - std::string object_prefix; - std::string object_suffix; - bool union_value_namespacing; - bool allow_non_utf8; - bool natural_utf8; - std::string include_prefix; - bool keep_include_path; - bool binary_schema_comments; - bool binary_schema_builtins; - bool binary_schema_gen_embed; - std::string go_import; - std::string go_namespace; - bool protobuf_ascii_alike; - bool size_prefixed; - std::string root_type; - bool force_defaults; - bool java_primitive_has_method; - bool cs_gen_json_serializer; - std::vector<std::string> cpp_includes; - std::string cpp_std; - bool cpp_static_reflection; - std::string proto_namespace_suffix; - std::string filename_suffix; - std::string filename_extension; - bool no_warnings; - - // Possible options for the more general generator below. - enum Language { - kJava = 1 << 0, - kCSharp = 1 << 1, - kGo = 1 << 2, - kCpp = 1 << 3, - kPython = 1 << 5, - kPhp = 1 << 6, - kJson = 1 << 7, - kBinary = 1 << 8, - kTs = 1 << 9, - kJsonSchema = 1 << 10, - kDart = 1 << 11, - kLua = 1 << 12, - kLobster = 1 << 13, - kRust = 1 << 14, - kKotlin = 1 << 15, - kSwift = 1 << 16, - kCppYandexMapsIter = 1 << 17, - kMAX - }; - - Language lang; - - enum MiniReflect { kNone, kTypes, kTypesAndNames }; - - MiniReflect mini_reflect; - - // If set, require all fields in a table to be explicitly numbered. - bool require_explicit_ids; - - // The corresponding language bit will be set if a language is included - // for code generation. - unsigned long lang_to_generate; - - // If set (default behavior), empty string fields will be set to nullptr to - // make the flatbuffer more compact. - bool set_empty_strings_to_null; - - // If set (default behavior), empty vector fields will be set to nullptr to - // make the flatbuffer more compact. - bool set_empty_vectors_to_null; - - IDLOptions() - : gen_jvmstatic(false), - use_flexbuffers(false), - strict_json(false), - output_default_scalars_in_json(false), - indent_step(2), - output_enum_identifiers(true), - prefixed_enums(true), - scoped_enums(false), - include_dependence_headers(true), - mutable_buffer(false), - one_file(false), - proto_mode(false), - proto_oneof_union(false), - generate_all(false), - skip_unexpected_fields_in_json(false), - generate_name_strings(false), - generate_object_based_api(false), - gen_compare(false), - cpp_object_api_pointer_type("std::unique_ptr"), - cpp_object_api_string_flexible_constructor(false), - cpp_direct_copy(true), - gen_nullable(false), - java_checkerframework(false), - gen_generated(false), - object_suffix("T"), - union_value_namespacing(true), - allow_non_utf8(false), - natural_utf8(false), - keep_include_path(false), - binary_schema_comments(false), - binary_schema_builtins(false), - binary_schema_gen_embed(false), - protobuf_ascii_alike(false), - size_prefixed(false), - force_defaults(false), - java_primitive_has_method(false), - cs_gen_json_serializer(false), - cpp_static_reflection(false), - filename_suffix("_generated"), - filename_extension(), - no_warnings(false), - lang(IDLOptions::kJava), - mini_reflect(IDLOptions::kNone), - require_explicit_ids(false), - lang_to_generate(0), - set_empty_strings_to_null(true), - set_empty_vectors_to_null(true) {} -}; - -// This encapsulates where the parser is in the current source file. -struct ParserState { - ParserState() - : cursor_(nullptr), - line_start_(nullptr), - line_(0), - token_(-1), - attr_is_trivial_ascii_string_(true) {} - - protected: - void ResetState(const char *source) { - cursor_ = source; - line_ = 0; - MarkNewLine(); - } - - void MarkNewLine() { - line_start_ = cursor_; - line_ += 1; - } - - int64_t CursorPosition() const { - FLATBUFFERS_ASSERT(cursor_ && line_start_ && cursor_ >= line_start_); - return static_cast<int64_t>(cursor_ - line_start_); - } - - const char *cursor_; - const char *line_start_; - int line_; // the current line being parsed - int token_; - - // Flag: text in attribute_ is true ASCII string without escape - // sequences. Only printable ASCII (without [\t\r\n]). - // Used for number-in-string (and base64 string in future). - bool attr_is_trivial_ascii_string_; - std::string attribute_; - std::vector<std::string> doc_comment_; -}; - -// A way to make error propagation less error prone by requiring values to be -// checked. -// Once you create a value of this type you must either: -// - Call Check() on it. -// - Copy or assign it to another value. -// Failure to do so leads to an assert. -// This guarantees that this as return value cannot be ignored. -class CheckedError { - public: - explicit CheckedError(bool error) - : is_error_(error), has_been_checked_(false) {} - - CheckedError &operator=(const CheckedError &other) { - is_error_ = other.is_error_; - has_been_checked_ = false; - other.has_been_checked_ = true; - return *this; - } - - CheckedError(const CheckedError &other) { - *this = other; // Use assignment operator. - } - - ~CheckedError() { FLATBUFFERS_ASSERT(has_been_checked_); } - - bool Check() { - has_been_checked_ = true; - return is_error_; - } - - private: - bool is_error_; - mutable bool has_been_checked_; -}; - -// Additionally, in GCC we can get these errors statically, for additional -// assurance: -// clang-format off -#ifdef __GNUC__ -#define FLATBUFFERS_CHECKED_ERROR CheckedError \ - __attribute__((warn_unused_result)) -#else -#define FLATBUFFERS_CHECKED_ERROR CheckedError -#endif -// clang-format on - -class Parser : public ParserState { - public: - explicit Parser(const IDLOptions &options = IDLOptions()) - : current_namespace_(nullptr), - empty_namespace_(nullptr), - flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL), - root_struct_def_(nullptr), - opts(options), - uses_flexbuffers_(false), - advanced_features_(0), - source_(nullptr), - anonymous_counter_(0), - parse_depth_counter_(0) { - if (opts.force_defaults) { builder_.ForceDefaults(true); } - // Start out with the empty namespace being current. - empty_namespace_ = new Namespace(); - namespaces_.push_back(empty_namespace_); - current_namespace_ = empty_namespace_; - known_attributes_["deprecated"] = true; - known_attributes_["required"] = true; - known_attributes_["key"] = true; - known_attributes_["shared"] = true; - known_attributes_["hash"] = true; - known_attributes_["id"] = true; - known_attributes_["force_align"] = true; - known_attributes_["bit_flags"] = true; - known_attributes_["original_order"] = true; - known_attributes_["nested_flatbuffer"] = true; - known_attributes_["csharp_partial"] = true; - known_attributes_["streaming"] = true; - known_attributes_["idempotent"] = true; - known_attributes_["cpp_type"] = true; - known_attributes_["cpp_ptr_type"] = true; - known_attributes_["cpp_ptr_type_get"] = true; - known_attributes_["cpp_str_type"] = true; - known_attributes_["cpp_str_flex_ctor"] = true; - known_attributes_["native_inline"] = true; - known_attributes_["native_custom_alloc"] = true; - known_attributes_["native_type"] = true; - known_attributes_["native_type_pack_name"] = true; - known_attributes_["native_default"] = true; - known_attributes_["flexbuffer"] = true; - known_attributes_["private"] = true; - } - - ~Parser() { - for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) { - delete *it; - } - } - - // Parse the string containing either schema or JSON data, which will - // populate the SymbolTable's or the FlatBufferBuilder above. - // include_paths is used to resolve any include statements, and typically - // should at least include the project path (where you loaded source_ from). - // include_paths must be nullptr terminated if specified. - // If include_paths is nullptr, it will attempt to load from the current - // directory. - // If the source was loaded from a file and isn't an include file, - // supply its name in source_filename. - // All paths specified in this call must be in posix format, if you accept - // paths from user input, please call PosixPath on them first. - bool Parse(const char *_source, const char **include_paths = nullptr, - const char *source_filename = nullptr); - - bool ParseJson(const char *json, const char *json_filename = nullptr); - - // Set the root type. May override the one set in the schema. - bool SetRootType(const char *name); - - // Mark all definitions as already having code generated. - void MarkGenerated(); - - // Get the files recursively included by the given file. The returned - // container will have at least the given file. - std::set<std::string> GetIncludedFilesRecursive( - const std::string &file_name) const; - - // Fills builder_ with a binary version of the schema parsed. - // See reflection/reflection.fbs - void Serialize(); - - // Deserialize a schema buffer - bool Deserialize(const uint8_t *buf, const size_t size); - - // Fills internal structure as if the schema passed had been loaded by parsing - // with Parse except that included filenames will not be populated. - bool Deserialize(const reflection::Schema *schema); - - Type *DeserializeType(const reflection::Type *type); - - // Checks that the schema represented by this parser is a safe evolution - // of the schema provided. Returns non-empty error on any problems. - std::string ConformTo(const Parser &base); - - // Similar to Parse(), but now only accepts JSON to be parsed into a - // FlexBuffer. - bool ParseFlexBuffer(const char *source, const char *source_filename, - flexbuffers::Builder *builder); - - StructDef *LookupStruct(const std::string &id) const; - StructDef *LookupStructThruParentNamespaces(const std::string &id) const; - - std::string UnqualifiedName(const std::string &fullQualifiedName); - - FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg); - - // @brief Verify that any of 'opts.lang_to_generate' supports Optional scalars - // in a schema. - // @param opts Options used to parce a schema and generate code. - static bool SupportsOptionalScalars(const flatbuffers::IDLOptions &opts); - - private: - class ParseDepthGuard; - - void Message(const std::string &msg); - void Warning(const std::string &msg); - FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val); - FLATBUFFERS_CHECKED_ERROR Next(); - FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark(); - bool Is(int t) const; - bool IsIdent(const char *id) const; - FLATBUFFERS_CHECKED_ERROR Expect(int t); - std::string TokenToStringId(int t) const; - EnumDef *LookupEnum(const std::string &id); - FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id, - std::string *last); - FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type &type); - FLATBUFFERS_CHECKED_ERROR ParseType(Type &type); - FLATBUFFERS_CHECKED_ERROR AddField(StructDef &struct_def, - const std::string &name, const Type &type, - FieldDef **dest); - FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def); - FLATBUFFERS_CHECKED_ERROR ParseString(Value &val, bool use_string_pooling); - FLATBUFFERS_CHECKED_ERROR ParseComma(); - FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field, - size_t parent_fieldn, - const StructDef *parent_struct_def, - uoffset_t count, - bool inside_vector = false); - template<typename F> - FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn, - const StructDef *struct_def, - F body); - FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def, - std::string *value, uoffset_t *ovalue); - void SerializeStruct(const StructDef &struct_def, const Value &val); - void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def, - const Value &val); - template<typename F> - FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(uoffset_t &count, F body); - FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue, - FieldDef *field, size_t fieldn); - FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array); - FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer( - Value &val, FieldDef *field, size_t fieldn, - const StructDef *parent_struct_def); - FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes); - FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, - bool check, Value &e, BaseType req, - bool *destmatch); - FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field); - FLATBUFFERS_CHECKED_ERROR TokenError(); - FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, - bool check_now); - FLATBUFFERS_CHECKED_ERROR ParseFunction(const std::string *name, Value &e); - FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, - std::string *result); - StructDef *LookupCreateStruct(const std::string &name, - bool create_if_new = true, - bool definition = false); - FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef **dest); - FLATBUFFERS_CHECKED_ERROR ParseNamespace(); - FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name, - StructDef **dest); - FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union, - EnumDef **dest); - FLATBUFFERS_CHECKED_ERROR ParseDecl(); - FLATBUFFERS_CHECKED_ERROR ParseService(); - FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def, - bool isextend, bool inside_oneof); - FLATBUFFERS_CHECKED_ERROR ParseProtoOption(); - FLATBUFFERS_CHECKED_ERROR ParseProtoKey(); - FLATBUFFERS_CHECKED_ERROR ParseProtoDecl(); - FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent(); - FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type); - FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue(); - FLATBUFFERS_CHECKED_ERROR ParseFlexBufferNumericConstant( - flexbuffers::Builder *builder); - FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder); - FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source, - const char *source_filename); - FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source, - const char **include_paths, - const char *source_filename); - FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source, - const char **include_paths, - const char *source_filename, - const char *include_filename); - FLATBUFFERS_CHECKED_ERROR DoParseJson(); - FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields, - StructDef *struct_def, - const char *suffix, BaseType baseType); - FLATBUFFERS_CHECKED_ERROR ParseAlignAttribute( - const std::string &align_constant, size_t min_align, size_t *align); - - bool SupportsAdvancedUnionFeatures() const; - bool SupportsAdvancedArrayFeatures() const; - bool SupportsOptionalScalars() const; - bool SupportsDefaultVectorsAndStrings() const; - Namespace *UniqueNamespace(Namespace *ns); - - FLATBUFFERS_CHECKED_ERROR RecurseError(); - template<typename F> CheckedError Recurse(F f); - - public: - SymbolTable<Type> types_; - SymbolTable<StructDef> structs_; - SymbolTable<EnumDef> enums_; - SymbolTable<ServiceDef> services_; - std::vector<Namespace *> namespaces_; - Namespace *current_namespace_; - Namespace *empty_namespace_; - std::string error_; // User readable error_ if Parse() == false - - FlatBufferBuilder builder_; // any data contained in the file - flexbuffers::Builder flex_builder_; - flexbuffers::Reference flex_root_; - StructDef *root_struct_def_; - std::string file_identifier_; - std::string file_extension_; - - std::map<uint64_t, std::string> included_files_; - std::map<std::string, std::set<std::string>> files_included_per_file_; - std::vector<std::string> native_included_files_; - - std::map<std::string, bool> known_attributes_; - - IDLOptions opts; - bool uses_flexbuffers_; - - uint64_t advanced_features_; - - private: - const char *source_; - - std::string file_being_parsed_; - - std::vector<std::pair<Value, FieldDef *>> field_stack_; - - int anonymous_counter_; - int parse_depth_counter_; // stack-overflow guard -}; - -// Utility functions for multiple generators: - -extern std::string MakeCamel(const std::string &in, bool first = true); - -extern std::string MakeScreamingCamel(const std::string &in); - -// Generate text (JSON) from a given FlatBuffer, and a given Parser -// object that has been populated with the corresponding schema. -// If ident_step is 0, no indentation will be generated. Additionally, -// if it is less than 0, no linefeeds will be generated either. -// See idl_gen_text.cpp. -// strict_json adds "quotes" around field names if true. -// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8 -// byte arrays in String values), returns false. -extern bool GenerateTextFromTable(const Parser &parser, const void *table, - const std::string &tablename, - std::string *text); -extern bool GenerateText(const Parser &parser, const void *flatbuffer, - std::string *text); -extern bool GenerateTextFile(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Json schema to string -// See idl_gen_json_schema.cpp. -extern bool GenerateJsonSchema(const Parser &parser, std::string *json); - -// Generate binary files from a given FlatBuffer, and a given Parser -// object that has been populated with the corresponding schema. -// See code_generators.cpp. -extern bool GenerateBinary(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a C++ header from the definitions in the Parser object. -// See idl_gen_cpp. -extern bool GenerateCPP(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate C# files from the definitions in the Parser object. -// See idl_gen_csharp.cpp. -extern bool GenerateCSharp(const Parser &parser, const std::string &path, - const std::string &file_name); - -extern bool GenerateDart(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Java files from the definitions in the Parser object. -// See idl_gen_java.cpp. -extern bool GenerateJava(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate JavaScript or TypeScript code from the definitions in the Parser -// object. See idl_gen_js. -extern bool GenerateTS(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Go files from the definitions in the Parser object. -// See idl_gen_go.cpp. -extern bool GenerateGo(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Php code from the definitions in the Parser object. -// See idl_gen_php. -extern bool GeneratePhp(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Python files from the definitions in the Parser object. -// See idl_gen_python.cpp. -extern bool GeneratePython(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Lobster files from the definitions in the Parser object. -// See idl_gen_lobster.cpp. -extern bool GenerateLobster(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Lua files from the definitions in the Parser object. -// See idl_gen_lua.cpp. -extern bool GenerateLua(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Rust files from the definitions in the Parser object. -// See idl_gen_rust.cpp. -extern bool GenerateRust(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Json schema file -// See idl_gen_json_schema.cpp. -extern bool GenerateJsonSchema(const Parser &parser, const std::string &path, - const std::string &file_name); - -extern bool GenerateKotlin(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Swift classes. -// See idl_gen_swift.cpp -extern bool GenerateSwift(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a schema file from the internal representation, useful after -// parsing a .proto schema. -extern std::string GenerateFBS(const Parser &parser, - const std::string &file_name); -extern bool GenerateFBS(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a C++ header for reading with templated file iterator from -// the definitions in the Parser object. -// See idl_gen_cpp_yandex_maps_iter.cpp. -extern std::string GenerateCPPYandexMapsIter(const Parser &parser, - const std::string &include_guard_ident); -extern bool GenerateCPPYandexMapsIter(const Parser &parser, - const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated TypeScript code. -// See idl_gen_ts.cpp. -extern std::string TSMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated C++ header. -// See idl_gen_cpp.cpp. -extern std::string CPPMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated Dart code -// see idl_gen_dart.cpp -extern std::string DartMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated Rust code. -// See idl_gen_rust.cpp. -extern std::string RustMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for generated Java or C# files. -// See code_generators.cpp. -extern std::string JavaCSharpMakeRule(const Parser &parser, - const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated text (JSON) files. -// See idl_gen_text.cpp. -extern std::string TextMakeRule(const Parser &parser, const std::string &path, - const std::string &file_names); - -// Generate a make rule for the generated binary files. -// See code_generators.cpp. -extern std::string BinaryMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Cpp interfaces. -// See idl_gen_grpc.cpp. -bool GenerateCppGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Go interfaces. -// See idl_gen_grpc.cpp. -bool GenerateGoGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Java classes. -// See idl_gen_grpc.cpp -bool GenerateJavaGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Python interfaces. -// See idl_gen_grpc.cpp. -bool GeneratePythonGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Swift interfaces. -// See idl_gen_grpc.cpp. -extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -extern bool GenerateTSGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); -} // namespace flatbuffers - -#endif // FLATBUFFERS_IDL_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/reflection.h b/contrib/libs/flatbuffers/include/flatbuffers/reflection.h deleted file mode 100644 index d268a3ffea..0000000000 --- a/contrib/libs/flatbuffers/include/flatbuffers/reflection.h +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright 2015 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_REFLECTION_H_ -#define FLATBUFFERS_REFLECTION_H_ - -// This is somewhat of a circular dependency because flatc (and thus this -// file) is needed to generate this header in the first place. -// Should normally not be a problem since it can be generated by the -// previous version of flatc whenever this code needs to change. -// See reflection/generate_code.sh -#include "reflection_generated.h" - -// Helper functionality for reflection. - -namespace flatbuffers { - -// ------------------------- GETTERS ------------------------- - -inline bool IsScalar(reflection::BaseType t) { - return t >= reflection::UType && t <= reflection::Double; -} -inline bool IsInteger(reflection::BaseType t) { - return t >= reflection::UType && t <= reflection::ULong; -} -inline bool IsFloat(reflection::BaseType t) { - return t == reflection::Float || t == reflection::Double; -} -inline bool IsLong(reflection::BaseType t) { - return t == reflection::Long || t == reflection::ULong; -} - -// Size of a basic type, don't use with structs. -inline size_t GetTypeSize(reflection::BaseType base_type) { - // This needs to correspond to the BaseType enum. - static size_t sizes[] = { - 0, // None - 1, // UType - 1, // Bool - 1, // Byte - 1, // UByte - 2, // Short - 2, // UShort - 4, // Int - 4, // UInt - 8, // Long - 8, // ULong - 4, // Float - 8, // Double - 4, // String - 4, // Vector - 4, // Obj - 4, // Union - 0, // Array. Only used in structs. 0 was chosen to prevent out-of-bounds - // errors. - - 0 // MaxBaseType. This must be kept the last entry in this array. - }; - static_assert(sizeof(sizes) / sizeof(size_t) == reflection::MaxBaseType + 1, - "Size of sizes[] array does not match the count of BaseType " - "enum values."); - return sizes[base_type]; -} - -// Same as above, but now correctly returns the size of a struct if -// the field (or vector element) is a struct. -inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index, - const reflection::Schema &schema) { - if (base_type == reflection::Obj && - schema.objects()->Get(type_index)->is_struct()) { - return schema.objects()->Get(type_index)->bytesize(); - } else { - return GetTypeSize(base_type); - } -} - -// Get the root, regardless of what type it is. -inline Table *GetAnyRoot(uint8_t *flatbuf) { - return GetMutableRoot<Table>(flatbuf); -} -inline const Table *GetAnyRoot(const uint8_t *flatbuf) { - return GetRoot<Table>(flatbuf); -} - -// Get a field's default, if you know it's an integer, and its exact type. -template<typename T> T GetFieldDefaultI(const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return static_cast<T>(field.default_integer()); -} - -// Get a field's default, if you know it's floating point and its exact type. -template<typename T> T GetFieldDefaultF(const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return static_cast<T>(field.default_real()); -} - -// Get a field, if you know it's an integer, and its exact type. -template<typename T> -T GetFieldI(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return table.GetField<T>(field.offset(), - static_cast<T>(field.default_integer())); -} - -// Get a field, if you know it's floating point and its exact type. -template<typename T> -T GetFieldF(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return table.GetField<T>(field.offset(), - static_cast<T>(field.default_real())); -} - -// Get a field, if you know it's a string. -inline const String *GetFieldS(const Table &table, - const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::String); - return table.GetPointer<const String *>(field.offset()); -} - -// Get a field, if you know it's a vector. -template<typename T> -Vector<T> *GetFieldV(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Vector && - sizeof(T) == GetTypeSize(field.type()->element())); - return table.GetPointer<Vector<T> *>(field.offset()); -} - -// Get a field, if you know it's a vector, generically. -// To actually access elements, use the return value together with -// field.type()->element() in any of GetAnyVectorElemI below etc. -inline VectorOfAny *GetFieldAnyV(const Table &table, - const reflection::Field &field) { - return table.GetPointer<VectorOfAny *>(field.offset()); -} - -// Get a field, if you know it's a table. -inline Table *GetFieldT(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj || - field.type()->base_type() == reflection::Union); - return table.GetPointer<Table *>(field.offset()); -} - -// Get a field, if you know it's a struct. -inline const Struct *GetFieldStruct(const Table &table, - const reflection::Field &field) { - // TODO: This does NOT check if the field is a table or struct, but we'd need - // access to the schema to check the is_struct flag. - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj); - return table.GetStruct<const Struct *>(field.offset()); -} - -// Get a structure's field, if you know it's a struct. -inline const Struct *GetFieldStruct(const Struct &structure, - const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj); - return structure.GetStruct<const Struct *>(field.offset()); -} - -// Raw helper functions used below: get any value in memory as a 64bit int, a -// double or a string. -// All scalars get static_cast to an int64_t, strings use strtoull, every other -// data type returns 0. -int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data); -// All scalars static cast to double, strings use strtod, every other data -// type is 0.0. -double GetAnyValueF(reflection::BaseType type, const uint8_t *data); -// All scalars converted using stringstream, strings as-is, and all other -// data types provide some level of debug-pretty-printing. -std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data, - const reflection::Schema *schema, int type_index); - -// Get any table field as a 64bit int, regardless of what type it is. -inline int64_t GetAnyFieldI(const Table &table, - const reflection::Field &field) { - auto field_ptr = table.GetAddressOf(field.offset()); - return field_ptr ? GetAnyValueI(field.type()->base_type(), field_ptr) - : field.default_integer(); -} - -// Get any table field as a double, regardless of what type it is. -inline double GetAnyFieldF(const Table &table, const reflection::Field &field) { - auto field_ptr = table.GetAddressOf(field.offset()); - return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr) - : field.default_real(); -} - -// Get any table field as a string, regardless of what type it is. -// You may pass nullptr for the schema if you don't care to have fields that -// are of table type pretty-printed. -inline std::string GetAnyFieldS(const Table &table, - const reflection::Field &field, - const reflection::Schema *schema) { - auto field_ptr = table.GetAddressOf(field.offset()); - return field_ptr ? GetAnyValueS(field.type()->base_type(), field_ptr, schema, - field.type()->index()) - : ""; -} - -// Get any struct field as a 64bit int, regardless of what type it is. -inline int64_t GetAnyFieldI(const Struct &st, const reflection::Field &field) { - return GetAnyValueI(field.type()->base_type(), - st.GetAddressOf(field.offset())); -} - -// Get any struct field as a double, regardless of what type it is. -inline double GetAnyFieldF(const Struct &st, const reflection::Field &field) { - return GetAnyValueF(field.type()->base_type(), - st.GetAddressOf(field.offset())); -} - -// Get any struct field as a string, regardless of what type it is. -inline std::string GetAnyFieldS(const Struct &st, - const reflection::Field &field) { - return GetAnyValueS(field.type()->base_type(), - st.GetAddressOf(field.offset()), nullptr, -1); -} - -// Get any vector element as a 64bit int, regardless of what type it is. -inline int64_t GetAnyVectorElemI(const VectorOfAny *vec, - reflection::BaseType elem_type, size_t i) { - return GetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i); -} - -// Get any vector element as a double, regardless of what type it is. -inline double GetAnyVectorElemF(const VectorOfAny *vec, - reflection::BaseType elem_type, size_t i) { - return GetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i); -} - -// Get any vector element as a string, regardless of what type it is. -inline std::string GetAnyVectorElemS(const VectorOfAny *vec, - reflection::BaseType elem_type, size_t i) { - return GetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, - nullptr, -1); -} - -// Get a vector element that's a table/string/vector from a generic vector. -// Pass Table/String/VectorOfAny as template parameter. -// Warning: does no typechecking. -template<typename T> -T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) { - auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i; - return reinterpret_cast<T *>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr)); -} - -// Get the inline-address of a vector element. Useful for Structs (pass Struct -// as template arg), or being able to address a range of scalars in-line. -// Get elem_size from GetTypeSizeInline(). -// Note: little-endian data on all platforms, use EndianScalar() instead of -// raw pointer access with scalars). -template<typename T> -T *GetAnyVectorElemAddressOf(const VectorOfAny *vec, size_t i, - size_t elem_size) { - return reinterpret_cast<T *>(vec->Data() + elem_size * i); -} - -// Similarly, for elements of tables. -template<typename T> -T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) { - return reinterpret_cast<T *>(table.GetAddressOf(field.offset())); -} - -// Similarly, for elements of structs. -template<typename T> -T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) { - return reinterpret_cast<T *>(st.GetAddressOf(field.offset())); -} - -// ------------------------- SETTERS ------------------------- - -// Set any scalar field, if you know its exact type. -template<typename T> -bool SetField(Table *table, const reflection::Field &field, T val) { - reflection::BaseType type = field.type()->base_type(); - if (!IsScalar(type)) { return false; } - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type)); - T def; - if (IsInteger(type)) { - def = GetFieldDefaultI<T>(field); - } else { - FLATBUFFERS_ASSERT(IsFloat(type)); - def = GetFieldDefaultF<T>(field); - } - return table->SetField(field.offset(), val, def); -} - -// Raw helper functions used below: set any value in memory as a 64bit int, a -// double or a string. -// These work for all scalar values, but do nothing for other data types. -// To set a string, see SetString below. -void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val); -void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val); -void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val); - -// Set any table field as a 64bit int, regardless of type what it is. -inline bool SetAnyFieldI(Table *table, const reflection::Field &field, - int64_t val) { - auto field_ptr = table->GetAddressOf(field.offset()); - if (!field_ptr) return val == GetFieldDefaultI<int64_t>(field); - SetAnyValueI(field.type()->base_type(), field_ptr, val); - return true; -} - -// Set any table field as a double, regardless of what type it is. -inline bool SetAnyFieldF(Table *table, const reflection::Field &field, - double val) { - auto field_ptr = table->GetAddressOf(field.offset()); - if (!field_ptr) return val == GetFieldDefaultF<double>(field); - SetAnyValueF(field.type()->base_type(), field_ptr, val); - return true; -} - -// Set any table field as a string, regardless of what type it is. -inline bool SetAnyFieldS(Table *table, const reflection::Field &field, - const char *val) { - auto field_ptr = table->GetAddressOf(field.offset()); - if (!field_ptr) return false; - SetAnyValueS(field.type()->base_type(), field_ptr, val); - return true; -} - -// Set any struct field as a 64bit int, regardless of type what it is. -inline void SetAnyFieldI(Struct *st, const reflection::Field &field, - int64_t val) { - SetAnyValueI(field.type()->base_type(), st->GetAddressOf(field.offset()), - val); -} - -// Set any struct field as a double, regardless of type what it is. -inline void SetAnyFieldF(Struct *st, const reflection::Field &field, - double val) { - SetAnyValueF(field.type()->base_type(), st->GetAddressOf(field.offset()), - val); -} - -// Set any struct field as a string, regardless of type what it is. -inline void SetAnyFieldS(Struct *st, const reflection::Field &field, - const char *val) { - SetAnyValueS(field.type()->base_type(), st->GetAddressOf(field.offset()), - val); -} - -// Set any vector element as a 64bit int, regardless of type what it is. -inline void SetAnyVectorElemI(VectorOfAny *vec, reflection::BaseType elem_type, - size_t i, int64_t val) { - SetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val); -} - -// Set any vector element as a double, regardless of type what it is. -inline void SetAnyVectorElemF(VectorOfAny *vec, reflection::BaseType elem_type, - size_t i, double val) { - SetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val); -} - -// Set any vector element as a string, regardless of type what it is. -inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type, - size_t i, const char *val) { - SetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val); -} - -// ------------------------- RESIZING SETTERS ------------------------- - -// "smart" pointer for use with resizing vectors: turns a pointer inside -// a vector into a relative offset, such that it is not affected by resizes. -template<typename T, typename U> class pointer_inside_vector { - public: - pointer_inside_vector(T *ptr, std::vector<U> &vec) - : offset_(reinterpret_cast<uint8_t *>(ptr) - - reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))), - vec_(vec) {} - - T *operator*() const { - return reinterpret_cast<T *>( - reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec_)) + offset_); - } - T *operator->() const { return operator*(); } - - private: - size_t offset_; - std::vector<U> &vec_; -}; - -// Helper to create the above easily without specifying template args. -template<typename T, typename U> -pointer_inside_vector<T, U> piv(T *ptr, std::vector<U> &vec) { - return pointer_inside_vector<T, U>(ptr, vec); -} - -inline const char *UnionTypeFieldSuffix() { return "_type"; } - -// Helper to figure out the actual table type a union refers to. -inline const reflection::Object &GetUnionType( - const reflection::Schema &schema, const reflection::Object &parent, - const reflection::Field &unionfield, const Table &table) { - auto enumdef = schema.enums()->Get(unionfield.type()->index()); - // TODO: this is clumsy and slow, but no other way to find it? - auto type_field = parent.fields()->LookupByKey( - (unionfield.name()->str() + UnionTypeFieldSuffix()).c_str()); - FLATBUFFERS_ASSERT(type_field); - auto union_type = GetFieldI<uint8_t>(table, *type_field); - auto enumval = enumdef->values()->LookupByKey(union_type); - return *enumval->object(); -} - -// Changes the contents of a string inside a FlatBuffer. FlatBuffer must -// live inside a std::vector so we can resize the buffer if needed. -// "str" must live inside "flatbuf" and may be invalidated after this call. -// If your FlatBuffer's root table is not the schema's root table, you should -// pass in your root_table type as well. -void SetString(const reflection::Schema &schema, const std::string &val, - const String *str, std::vector<uint8_t> *flatbuf, - const reflection::Object *root_table = nullptr); - -// Resizes a flatbuffers::Vector inside a FlatBuffer. FlatBuffer must -// live inside a std::vector so we can resize the buffer if needed. -// "vec" must live inside "flatbuf" and may be invalidated after this call. -// If your FlatBuffer's root table is not the schema's root table, you should -// pass in your root_table type as well. -uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize, - const VectorOfAny *vec, uoffset_t num_elems, - uoffset_t elem_size, std::vector<uint8_t> *flatbuf, - const reflection::Object *root_table = nullptr); - -template<typename T> -void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val, - const Vector<T> *vec, std::vector<uint8_t> *flatbuf, - const reflection::Object *root_table = nullptr) { - auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size()); - auto newelems = ResizeAnyVector( - schema, newsize, reinterpret_cast<const VectorOfAny *>(vec), vec->size(), - static_cast<uoffset_t>(sizeof(T)), flatbuf, root_table); - // Set new elements to "val". - for (int i = 0; i < delta_elem; i++) { - auto loc = newelems + i * sizeof(T); - auto is_scalar = flatbuffers::is_scalar<T>::value; - if (is_scalar) { - WriteScalar(loc, val); - } else { // struct - *reinterpret_cast<T *>(loc) = val; - } - } -} - -// Adds any new data (in the form of a new FlatBuffer) to an existing -// FlatBuffer. This can be used when any of the above methods are not -// sufficient, in particular for adding new tables and new fields. -// This is potentially slightly less efficient than a FlatBuffer constructed -// in one piece, since the new FlatBuffer doesn't share any vtables with the -// existing one. -// The return value can now be set using Vector::MutateOffset or SetFieldT -// below. -const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf, - const uint8_t *newbuf, size_t newlen); - -inline bool SetFieldT(Table *table, const reflection::Field &field, - const uint8_t *val) { - FLATBUFFERS_ASSERT(sizeof(uoffset_t) == - GetTypeSize(field.type()->base_type())); - return table->SetPointer(field.offset(), val); -} - -// ------------------------- COPYING ------------------------- - -// Generic copying of tables from a FlatBuffer into a FlatBuffer builder. -// Can be used to do any kind of merging/selecting you may want to do out -// of existing buffers. Also useful to reconstruct a whole buffer if the -// above resizing functionality has introduced garbage in a buffer you want -// to remove. -// Note: this does not deal with DAGs correctly. If the table passed forms a -// DAG, the copy will be a tree instead (with duplicates). Strings can be -// shared however, by passing true for use_string_pooling. - -Offset<const Table *> CopyTable(FlatBufferBuilder &fbb, - const reflection::Schema &schema, - const reflection::Object &objectdef, - const Table &table, - bool use_string_pooling = false); - -// Verifies the provided flatbuffer using reflection. -// root should point to the root type for this flatbuffer. -// buf should point to the start of flatbuffer data. -// length specifies the size of the flatbuffer data. -bool Verify(const reflection::Schema &schema, const reflection::Object &root, - const uint8_t *buf, size_t length, uoffset_t max_depth = 64, - uoffset_t max_tables = 1000000); - -} // namespace flatbuffers - -#endif // FLATBUFFERS_REFLECTION_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h b/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h deleted file mode 100644 index 93dc4b88b7..0000000000 --- a/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h +++ /dev/null @@ -1,1278 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - - -#ifndef FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_ -#define FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_ - -#include "flatbuffers.h" - -namespace reflection { - -struct Type; -struct TypeBuilder; - -struct KeyValue; -struct KeyValueBuilder; - -struct EnumVal; -struct EnumValBuilder; - -struct Enum; -struct EnumBuilder; - -struct Field; -struct FieldBuilder; - -struct Object; -struct ObjectBuilder; - -struct RPCCall; -struct RPCCallBuilder; - -struct Service; -struct ServiceBuilder; - -struct Schema; -struct SchemaBuilder; - -enum BaseType { - None = 0, - UType = 1, - Bool = 2, - Byte = 3, - UByte = 4, - Short = 5, - UShort = 6, - Int = 7, - UInt = 8, - Long = 9, - ULong = 10, - Float = 11, - Double = 12, - String = 13, - Vector = 14, - Obj = 15, - Union = 16, - Array = 17, - MaxBaseType = 18 -}; - -inline const BaseType (&EnumValuesBaseType())[19] { - static const BaseType values[] = { - None, - UType, - Bool, - Byte, - UByte, - Short, - UShort, - Int, - UInt, - Long, - ULong, - Float, - Double, - String, - Vector, - Obj, - Union, - Array, - MaxBaseType - }; - return values; -} - -inline const char * const *EnumNamesBaseType() { - static const char * const names[20] = { - "None", - "UType", - "Bool", - "Byte", - "UByte", - "Short", - "UShort", - "Int", - "UInt", - "Long", - "ULong", - "Float", - "Double", - "String", - "Vector", - "Obj", - "Union", - "Array", - "MaxBaseType", - nullptr - }; - return names; -} - -inline const char *EnumNameBaseType(BaseType e) { - if (flatbuffers::IsOutRange(e, None, MaxBaseType)) return ""; - const size_t index = static_cast<size_t>(e); - return EnumNamesBaseType()[index]; -} - -enum AdvancedFeatures { - AdvancedArrayFeatures = 1ULL, - AdvancedUnionFeatures = 2ULL, - OptionalScalars = 4ULL, - DefaultVectorsAndStrings = 8ULL -}; - -inline const AdvancedFeatures (&EnumValuesAdvancedFeatures())[4] { - static const AdvancedFeatures values[] = { - AdvancedArrayFeatures, - AdvancedUnionFeatures, - OptionalScalars, - DefaultVectorsAndStrings - }; - return values; -} - -inline const char * const *EnumNamesAdvancedFeatures() { - static const char * const names[9] = { - "AdvancedArrayFeatures", - "AdvancedUnionFeatures", - "", - "OptionalScalars", - "", - "", - "", - "DefaultVectorsAndStrings", - nullptr - }; - return names; -} - -inline const char *EnumNameAdvancedFeatures(AdvancedFeatures e) { - if (flatbuffers::IsOutRange(e, AdvancedArrayFeatures, DefaultVectorsAndStrings)) return ""; - const size_t index = static_cast<size_t>(e) - static_cast<size_t>(AdvancedArrayFeatures); - return EnumNamesAdvancedFeatures()[index]; -} - -struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef TypeBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_BASE_TYPE = 4, - VT_ELEMENT = 6, - VT_INDEX = 8, - VT_FIXED_LENGTH = 10 - }; - reflection::BaseType base_type() const { - return static_cast<reflection::BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0)); - } - reflection::BaseType element() const { - return static_cast<reflection::BaseType>(GetField<int8_t>(VT_ELEMENT, 0)); - } - int32_t index() const { - return GetField<int32_t>(VT_INDEX, -1); - } - uint16_t fixed_length() const { - return GetField<uint16_t>(VT_FIXED_LENGTH, 0); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField<int8_t>(verifier, VT_BASE_TYPE) && - VerifyField<int8_t>(verifier, VT_ELEMENT) && - VerifyField<int32_t>(verifier, VT_INDEX) && - VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH) && - verifier.EndTable(); - } -}; - -struct TypeBuilder { - typedef Type Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_base_type(reflection::BaseType base_type) { - fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0); - } - void add_element(reflection::BaseType element) { - fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0); - } - void add_index(int32_t index) { - fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1); - } - void add_fixed_length(uint16_t fixed_length) { - fbb_.AddElement<uint16_t>(Type::VT_FIXED_LENGTH, fixed_length, 0); - } - explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<Type> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Type>(end); - return o; - } -}; - -inline flatbuffers::Offset<Type> CreateType( - flatbuffers::FlatBufferBuilder &_fbb, - reflection::BaseType base_type = reflection::None, - reflection::BaseType element = reflection::None, - int32_t index = -1, - uint16_t fixed_length = 0) { - TypeBuilder builder_(_fbb); - builder_.add_index(index); - builder_.add_fixed_length(fixed_length); - builder_.add_element(element); - builder_.add_base_type(base_type); - return builder_.Finish(); -} - -struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef KeyValueBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_KEY = 4, - VT_VALUE = 6 - }; - const flatbuffers::String *key() const { - return GetPointer<const flatbuffers::String *>(VT_KEY); - } - bool KeyCompareLessThan(const KeyValue *o) const { - return *key() < *o->key(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(key()->c_str(), val); - } - const flatbuffers::String *value() const { - return GetPointer<const flatbuffers::String *>(VT_VALUE); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_KEY) && - verifier.VerifyString(key()) && - VerifyOffset(verifier, VT_VALUE) && - verifier.VerifyString(value()) && - verifier.EndTable(); - } -}; - -struct KeyValueBuilder { - typedef KeyValue Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_key(flatbuffers::Offset<flatbuffers::String> key) { - fbb_.AddOffset(KeyValue::VT_KEY, key); - } - void add_value(flatbuffers::Offset<flatbuffers::String> value) { - fbb_.AddOffset(KeyValue::VT_VALUE, value); - } - explicit KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<KeyValue> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<KeyValue>(end); - fbb_.Required(o, KeyValue::VT_KEY); - return o; - } -}; - -inline flatbuffers::Offset<KeyValue> CreateKeyValue( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> key = 0, - flatbuffers::Offset<flatbuffers::String> value = 0) { - KeyValueBuilder builder_(_fbb); - builder_.add_value(value); - builder_.add_key(key); - return builder_.Finish(); -} - -inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *key = nullptr, - const char *value = nullptr) { - auto key__ = key ? _fbb.CreateString(key) : 0; - auto value__ = value ? _fbb.CreateString(value) : 0; - return reflection::CreateKeyValue( - _fbb, - key__, - value__); -} - -struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef EnumValBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_VALUE = 6, - VT_OBJECT = 8, - VT_UNION_TYPE = 10, - VT_DOCUMENTATION = 12 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - int64_t value() const { - return GetField<int64_t>(VT_VALUE, 0); - } - bool KeyCompareLessThan(const EnumVal *o) const { - return value() < o->value(); - } - int KeyCompareWithValue(int64_t val) const { - return static_cast<int>(value() > val) - static_cast<int>(value() < val); - } - const reflection::Object *object() const { - return GetPointer<const reflection::Object *>(VT_OBJECT); - } - const reflection::Type *union_type() const { - return GetPointer<const reflection::Type *>(VT_UNION_TYPE); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyField<int64_t>(verifier, VT_VALUE) && - VerifyOffset(verifier, VT_OBJECT) && - verifier.VerifyTable(object()) && - VerifyOffset(verifier, VT_UNION_TYPE) && - verifier.VerifyTable(union_type()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct EnumValBuilder { - typedef EnumVal Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(EnumVal::VT_NAME, name); - } - void add_value(int64_t value) { - fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0); - } - void add_object(flatbuffers::Offset<reflection::Object> object) { - fbb_.AddOffset(EnumVal::VT_OBJECT, object); - } - void add_union_type(flatbuffers::Offset<reflection::Type> union_type) { - fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(EnumVal::VT_DOCUMENTATION, documentation); - } - explicit EnumValBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<EnumVal> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<EnumVal>(end); - fbb_.Required(o, EnumVal::VT_NAME); - return o; - } -}; - -inline flatbuffers::Offset<EnumVal> CreateEnumVal( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, - int64_t value = 0, - flatbuffers::Offset<reflection::Object> object = 0, - flatbuffers::Offset<reflection::Type> union_type = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { - EnumValBuilder builder_(_fbb); - builder_.add_value(value); - builder_.add_documentation(documentation); - builder_.add_union_type(union_type); - builder_.add_object(object); - builder_.add_name(name); - return builder_.Finish(); -} - -inline flatbuffers::Offset<EnumVal> CreateEnumValDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - int64_t value = 0, - flatbuffers::Offset<reflection::Object> object = 0, - flatbuffers::Offset<reflection::Type> union_type = 0, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateEnumVal( - _fbb, - name__, - value, - object, - union_type, - documentation__); -} - -struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef EnumBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_VALUES = 6, - VT_IS_UNION = 8, - VT_UNDERLYING_TYPE = 10, - VT_ATTRIBUTES = 12, - VT_DOCUMENTATION = 14 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const Enum *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *values() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *>(VT_VALUES); - } - bool is_union() const { - return GetField<uint8_t>(VT_IS_UNION, 0) != 0; - } - const reflection::Type *underlying_type() const { - return GetPointer<const reflection::Type *>(VT_UNDERLYING_TYPE); - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_VALUES) && - verifier.VerifyVector(values()) && - verifier.VerifyVectorOfTables(values()) && - VerifyField<uint8_t>(verifier, VT_IS_UNION) && - VerifyOffsetRequired(verifier, VT_UNDERLYING_TYPE) && - verifier.VerifyTable(underlying_type()) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct EnumBuilder { - typedef Enum Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(Enum::VT_NAME, name); - } - void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values) { - fbb_.AddOffset(Enum::VT_VALUES, values); - } - void add_is_union(bool is_union) { - fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0); - } - void add_underlying_type(flatbuffers::Offset<reflection::Type> underlying_type) { - fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type); - } - void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(Enum::VT_DOCUMENTATION, documentation); - } - explicit EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<Enum> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Enum>(end); - fbb_.Required(o, Enum::VT_NAME); - fbb_.Required(o, Enum::VT_VALUES); - fbb_.Required(o, Enum::VT_UNDERLYING_TYPE); - return o; - } -}; - -inline flatbuffers::Offset<Enum> CreateEnum( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values = 0, - bool is_union = false, - flatbuffers::Offset<reflection::Type> underlying_type = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { - EnumBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_underlying_type(underlying_type); - builder_.add_values(values); - builder_.add_name(name); - builder_.add_is_union(is_union); - return builder_.Finish(); -} - -inline flatbuffers::Offset<Enum> CreateEnumDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - std::vector<flatbuffers::Offset<reflection::EnumVal>> *values = nullptr, - bool is_union = false, - flatbuffers::Offset<reflection::Type> underlying_type = 0, - std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto values__ = values ? _fbb.CreateVectorOfSortedTables<reflection::EnumVal>(values) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateEnum( - _fbb, - name__, - values__, - is_union, - underlying_type, - attributes__, - documentation__); -} - -struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef FieldBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_TYPE = 6, - VT_ID = 8, - VT_OFFSET = 10, - VT_DEFAULT_INTEGER = 12, - VT_DEFAULT_REAL = 14, - VT_DEPRECATED = 16, - VT_REQUIRED = 18, - VT_KEY = 20, - VT_ATTRIBUTES = 22, - VT_DOCUMENTATION = 24, - VT_OPTIONAL = 26 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const Field *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const reflection::Type *type() const { - return GetPointer<const reflection::Type *>(VT_TYPE); - } - uint16_t id() const { - return GetField<uint16_t>(VT_ID, 0); - } - uint16_t offset() const { - return GetField<uint16_t>(VT_OFFSET, 0); - } - int64_t default_integer() const { - return GetField<int64_t>(VT_DEFAULT_INTEGER, 0); - } - double default_real() const { - return GetField<double>(VT_DEFAULT_REAL, 0.0); - } - bool deprecated() const { - return GetField<uint8_t>(VT_DEPRECATED, 0) != 0; - } - bool required() const { - return GetField<uint8_t>(VT_REQUIRED, 0) != 0; - } - bool key() const { - return GetField<uint8_t>(VT_KEY, 0) != 0; - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } - bool optional() const { - return GetField<uint8_t>(VT_OPTIONAL, 0) != 0; - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_TYPE) && - verifier.VerifyTable(type()) && - VerifyField<uint16_t>(verifier, VT_ID) && - VerifyField<uint16_t>(verifier, VT_OFFSET) && - VerifyField<int64_t>(verifier, VT_DEFAULT_INTEGER) && - VerifyField<double>(verifier, VT_DEFAULT_REAL) && - VerifyField<uint8_t>(verifier, VT_DEPRECATED) && - VerifyField<uint8_t>(verifier, VT_REQUIRED) && - VerifyField<uint8_t>(verifier, VT_KEY) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - VerifyField<uint8_t>(verifier, VT_OPTIONAL) && - verifier.EndTable(); - } -}; - -struct FieldBuilder { - typedef Field Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(Field::VT_NAME, name); - } - void add_type(flatbuffers::Offset<reflection::Type> type) { - fbb_.AddOffset(Field::VT_TYPE, type); - } - void add_id(uint16_t id) { - fbb_.AddElement<uint16_t>(Field::VT_ID, id, 0); - } - void add_offset(uint16_t offset) { - fbb_.AddElement<uint16_t>(Field::VT_OFFSET, offset, 0); - } - void add_default_integer(int64_t default_integer) { - fbb_.AddElement<int64_t>(Field::VT_DEFAULT_INTEGER, default_integer, 0); - } - void add_default_real(double default_real) { - fbb_.AddElement<double>(Field::VT_DEFAULT_REAL, default_real, 0.0); - } - void add_deprecated(bool deprecated) { - fbb_.AddElement<uint8_t>(Field::VT_DEPRECATED, static_cast<uint8_t>(deprecated), 0); - } - void add_required(bool required) { - fbb_.AddElement<uint8_t>(Field::VT_REQUIRED, static_cast<uint8_t>(required), 0); - } - void add_key(bool key) { - fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0); - } - void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(Field::VT_DOCUMENTATION, documentation); - } - void add_optional(bool optional) { - fbb_.AddElement<uint8_t>(Field::VT_OPTIONAL, static_cast<uint8_t>(optional), 0); - } - explicit FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<Field> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Field>(end); - fbb_.Required(o, Field::VT_NAME); - fbb_.Required(o, Field::VT_TYPE); - return o; - } -}; - -inline flatbuffers::Offset<Field> CreateField( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, - flatbuffers::Offset<reflection::Type> type = 0, - uint16_t id = 0, - uint16_t offset = 0, - int64_t default_integer = 0, - double default_real = 0.0, - bool deprecated = false, - bool required = false, - bool key = false, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0, - bool optional = false) { - FieldBuilder builder_(_fbb); - builder_.add_default_real(default_real); - builder_.add_default_integer(default_integer); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_type(type); - builder_.add_name(name); - builder_.add_offset(offset); - builder_.add_id(id); - builder_.add_optional(optional); - builder_.add_key(key); - builder_.add_required(required); - builder_.add_deprecated(deprecated); - return builder_.Finish(); -} - -inline flatbuffers::Offset<Field> CreateFieldDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - flatbuffers::Offset<reflection::Type> type = 0, - uint16_t id = 0, - uint16_t offset = 0, - int64_t default_integer = 0, - double default_real = 0.0, - bool deprecated = false, - bool required = false, - bool key = false, - std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr, - bool optional = false) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateField( - _fbb, - name__, - type, - id, - offset, - default_integer, - default_real, - deprecated, - required, - key, - attributes__, - documentation__, - optional); -} - -struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef ObjectBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_FIELDS = 6, - VT_IS_STRUCT = 8, - VT_MINALIGN = 10, - VT_BYTESIZE = 12, - VT_ATTRIBUTES = 14, - VT_DOCUMENTATION = 16 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const Object *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *fields() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *>(VT_FIELDS); - } - bool is_struct() const { - return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0; - } - int32_t minalign() const { - return GetField<int32_t>(VT_MINALIGN, 0); - } - int32_t bytesize() const { - return GetField<int32_t>(VT_BYTESIZE, 0); - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_FIELDS) && - verifier.VerifyVector(fields()) && - verifier.VerifyVectorOfTables(fields()) && - VerifyField<uint8_t>(verifier, VT_IS_STRUCT) && - VerifyField<int32_t>(verifier, VT_MINALIGN) && - VerifyField<int32_t>(verifier, VT_BYTESIZE) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct ObjectBuilder { - typedef Object Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(Object::VT_NAME, name); - } - void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields) { - fbb_.AddOffset(Object::VT_FIELDS, fields); - } - void add_is_struct(bool is_struct) { - fbb_.AddElement<uint8_t>(Object::VT_IS_STRUCT, static_cast<uint8_t>(is_struct), 0); - } - void add_minalign(int32_t minalign) { - fbb_.AddElement<int32_t>(Object::VT_MINALIGN, minalign, 0); - } - void add_bytesize(int32_t bytesize) { - fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0); - } - void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(Object::VT_DOCUMENTATION, documentation); - } - explicit ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<Object> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Object>(end); - fbb_.Required(o, Object::VT_NAME); - fbb_.Required(o, Object::VT_FIELDS); - return o; - } -}; - -inline flatbuffers::Offset<Object> CreateObject( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields = 0, - bool is_struct = false, - int32_t minalign = 0, - int32_t bytesize = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { - ObjectBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_bytesize(bytesize); - builder_.add_minalign(minalign); - builder_.add_fields(fields); - builder_.add_name(name); - builder_.add_is_struct(is_struct); - return builder_.Finish(); -} - -inline flatbuffers::Offset<Object> CreateObjectDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - std::vector<flatbuffers::Offset<reflection::Field>> *fields = nullptr, - bool is_struct = false, - int32_t minalign = 0, - int32_t bytesize = 0, - std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto fields__ = fields ? _fbb.CreateVectorOfSortedTables<reflection::Field>(fields) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateObject( - _fbb, - name__, - fields__, - is_struct, - minalign, - bytesize, - attributes__, - documentation__); -} - -struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef RPCCallBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_REQUEST = 6, - VT_RESPONSE = 8, - VT_ATTRIBUTES = 10, - VT_DOCUMENTATION = 12 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const RPCCall *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const reflection::Object *request() const { - return GetPointer<const reflection::Object *>(VT_REQUEST); - } - const reflection::Object *response() const { - return GetPointer<const reflection::Object *>(VT_RESPONSE); - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_REQUEST) && - verifier.VerifyTable(request()) && - VerifyOffsetRequired(verifier, VT_RESPONSE) && - verifier.VerifyTable(response()) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct RPCCallBuilder { - typedef RPCCall Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(RPCCall::VT_NAME, name); - } - void add_request(flatbuffers::Offset<reflection::Object> request) { - fbb_.AddOffset(RPCCall::VT_REQUEST, request); - } - void add_response(flatbuffers::Offset<reflection::Object> response) { - fbb_.AddOffset(RPCCall::VT_RESPONSE, response); - } - void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(RPCCall::VT_DOCUMENTATION, documentation); - } - explicit RPCCallBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<RPCCall> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<RPCCall>(end); - fbb_.Required(o, RPCCall::VT_NAME); - fbb_.Required(o, RPCCall::VT_REQUEST); - fbb_.Required(o, RPCCall::VT_RESPONSE); - return o; - } -}; - -inline flatbuffers::Offset<RPCCall> CreateRPCCall( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, - flatbuffers::Offset<reflection::Object> request = 0, - flatbuffers::Offset<reflection::Object> response = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { - RPCCallBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_response(response); - builder_.add_request(request); - builder_.add_name(name); - return builder_.Finish(); -} - -inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - flatbuffers::Offset<reflection::Object> request = 0, - flatbuffers::Offset<reflection::Object> response = 0, - std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateRPCCall( - _fbb, - name__, - request, - response, - attributes__, - documentation__); -} - -struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef ServiceBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_CALLS = 6, - VT_ATTRIBUTES = 8, - VT_DOCUMENTATION = 10 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const Service *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *calls() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *>(VT_CALLS); - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffset(verifier, VT_CALLS) && - verifier.VerifyVector(calls()) && - verifier.VerifyVectorOfTables(calls()) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct ServiceBuilder { - typedef Service Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(Service::VT_NAME, name); - } - void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls) { - fbb_.AddOffset(Service::VT_CALLS, calls); - } - void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(Service::VT_DOCUMENTATION, documentation); - } - explicit ServiceBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<Service> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Service>(end); - fbb_.Required(o, Service::VT_NAME); - return o; - } -}; - -inline flatbuffers::Offset<Service> CreateService( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { - ServiceBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_calls(calls); - builder_.add_name(name); - return builder_.Finish(); -} - -inline flatbuffers::Offset<Service> CreateServiceDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - std::vector<flatbuffers::Offset<reflection::RPCCall>> *calls = nullptr, - std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto calls__ = calls ? _fbb.CreateVectorOfSortedTables<reflection::RPCCall>(calls) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateService( - _fbb, - name__, - calls__, - attributes__, - documentation__); -} - -struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef SchemaBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_OBJECTS = 4, - VT_ENUMS = 6, - VT_FILE_IDENT = 8, - VT_FILE_EXT = 10, - VT_ROOT_TABLE = 12, - VT_SERVICES = 14, - VT_ADVANCED_FEATURES = 16 - }; - const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *objects() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *>(VT_OBJECTS); - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *enums() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *>(VT_ENUMS); - } - const flatbuffers::String *file_ident() const { - return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT); - } - const flatbuffers::String *file_ext() const { - return GetPointer<const flatbuffers::String *>(VT_FILE_EXT); - } - const reflection::Object *root_table() const { - return GetPointer<const reflection::Object *>(VT_ROOT_TABLE); - } - const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *services() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *>(VT_SERVICES); - } - reflection::AdvancedFeatures advanced_features() const { - return static_cast<reflection::AdvancedFeatures>(GetField<uint64_t>(VT_ADVANCED_FEATURES, 0)); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_OBJECTS) && - verifier.VerifyVector(objects()) && - verifier.VerifyVectorOfTables(objects()) && - VerifyOffsetRequired(verifier, VT_ENUMS) && - verifier.VerifyVector(enums()) && - verifier.VerifyVectorOfTables(enums()) && - VerifyOffset(verifier, VT_FILE_IDENT) && - verifier.VerifyString(file_ident()) && - VerifyOffset(verifier, VT_FILE_EXT) && - verifier.VerifyString(file_ext()) && - VerifyOffset(verifier, VT_ROOT_TABLE) && - verifier.VerifyTable(root_table()) && - VerifyOffset(verifier, VT_SERVICES) && - verifier.VerifyVector(services()) && - verifier.VerifyVectorOfTables(services()) && - VerifyField<uint64_t>(verifier, VT_ADVANCED_FEATURES) && - verifier.EndTable(); - } -}; - -struct SchemaBuilder { - typedef Schema Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects) { - fbb_.AddOffset(Schema::VT_OBJECTS, objects); - } - void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums) { - fbb_.AddOffset(Schema::VT_ENUMS, enums); - } - void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) { - fbb_.AddOffset(Schema::VT_FILE_IDENT, file_ident); - } - void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) { - fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext); - } - void add_root_table(flatbuffers::Offset<reflection::Object> root_table) { - fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table); - } - void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services) { - fbb_.AddOffset(Schema::VT_SERVICES, services); - } - void add_advanced_features(reflection::AdvancedFeatures advanced_features) { - fbb_.AddElement<uint64_t>(Schema::VT_ADVANCED_FEATURES, static_cast<uint64_t>(advanced_features), 0); - } - explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<Schema> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Schema>(end); - fbb_.Required(o, Schema::VT_OBJECTS); - fbb_.Required(o, Schema::VT_ENUMS); - return o; - } -}; - -inline flatbuffers::Offset<Schema> CreateSchema( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums = 0, - flatbuffers::Offset<flatbuffers::String> file_ident = 0, - flatbuffers::Offset<flatbuffers::String> file_ext = 0, - flatbuffers::Offset<reflection::Object> root_table = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0, - reflection::AdvancedFeatures advanced_features = static_cast<reflection::AdvancedFeatures>(0)) { - SchemaBuilder builder_(_fbb); - builder_.add_advanced_features(advanced_features); - builder_.add_services(services); - builder_.add_root_table(root_table); - builder_.add_file_ext(file_ext); - builder_.add_file_ident(file_ident); - builder_.add_enums(enums); - builder_.add_objects(objects); - return builder_.Finish(); -} - -inline flatbuffers::Offset<Schema> CreateSchemaDirect( - flatbuffers::FlatBufferBuilder &_fbb, - std::vector<flatbuffers::Offset<reflection::Object>> *objects = nullptr, - std::vector<flatbuffers::Offset<reflection::Enum>> *enums = nullptr, - const char *file_ident = nullptr, - const char *file_ext = nullptr, - flatbuffers::Offset<reflection::Object> root_table = 0, - std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr, - reflection::AdvancedFeatures advanced_features = static_cast<reflection::AdvancedFeatures>(0)) { - auto objects__ = objects ? _fbb.CreateVectorOfSortedTables<reflection::Object>(objects) : 0; - auto enums__ = enums ? _fbb.CreateVectorOfSortedTables<reflection::Enum>(enums) : 0; - auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0; - auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0; - auto services__ = services ? _fbb.CreateVectorOfSortedTables<reflection::Service>(services) : 0; - return reflection::CreateSchema( - _fbb, - objects__, - enums__, - file_ident__, - file_ext__, - root_table, - services__, - advanced_features); -} - -inline const reflection::Schema *GetSchema(const void *buf) { - return flatbuffers::GetRoot<reflection::Schema>(buf); -} - -inline const reflection::Schema *GetSizePrefixedSchema(const void *buf) { - return flatbuffers::GetSizePrefixedRoot<reflection::Schema>(buf); -} - -inline const char *SchemaIdentifier() { - return "BFBS"; -} - -inline bool SchemaBufferHasIdentifier(const void *buf) { - return flatbuffers::BufferHasIdentifier( - buf, SchemaIdentifier()); -} - -inline bool VerifySchemaBuffer( - flatbuffers::Verifier &verifier) { - return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier()); -} - -inline bool VerifySizePrefixedSchemaBuffer( - flatbuffers::Verifier &verifier) { - return verifier.VerifySizePrefixedBuffer<reflection::Schema>(SchemaIdentifier()); -} - -inline const char *SchemaExtension() { - return "bfbs"; -} - -inline void FinishSchemaBuffer( - flatbuffers::FlatBufferBuilder &fbb, - flatbuffers::Offset<reflection::Schema> root) { - fbb.Finish(root, SchemaIdentifier()); -} - -inline void FinishSizePrefixedSchemaBuffer( - flatbuffers::FlatBufferBuilder &fbb, - flatbuffers::Offset<reflection::Schema> root) { - fbb.FinishSizePrefixed(root, SchemaIdentifier()); -} - -} // namespace reflection - -#endif // FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/util.h b/contrib/libs/flatbuffers/include/flatbuffers/util.h deleted file mode 100644 index 4493c561c2..0000000000 --- a/contrib/libs/flatbuffers/include/flatbuffers/util.h +++ /dev/null @@ -1,698 +0,0 @@ -/* - * Copyright 2014 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_UTIL_H_ -#define FLATBUFFERS_UTIL_H_ - -#include <errno.h> - -#include "base.h" -#include "stl_emulation.h" - -#ifndef FLATBUFFERS_PREFER_PRINTF -# include <sstream> -#else // FLATBUFFERS_PREFER_PRINTF -# include <float.h> -# include <stdio.h> -#endif // FLATBUFFERS_PREFER_PRINTF - -#include <iomanip> -#include <string> - -namespace flatbuffers { - -// @locale-independent functions for ASCII characters set. - -// Fast checking that character lies in closed range: [a <= x <= b] -// using one compare (conditional branch) operator. -inline bool check_ascii_range(char x, char a, char b) { - FLATBUFFERS_ASSERT(a <= b); - // (Hacker's Delight): `a <= x <= b` <=> `(x-a) <={u} (b-a)`. - // The x, a, b will be promoted to int and subtracted without overflow. - return static_cast<unsigned int>(x - a) <= static_cast<unsigned int>(b - a); -} - -// Case-insensitive isalpha -inline bool is_alpha(char c) { - // ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF). - return check_ascii_range(c & 0xDF, 'a' & 0xDF, 'z' & 0xDF); -} - -// Check for uppercase alpha -inline bool is_alpha_upper(char c) { return check_ascii_range(c, 'A', 'Z'); } - -// Check (case-insensitive) that `c` is equal to alpha. -inline bool is_alpha_char(char c, char alpha) { - FLATBUFFERS_ASSERT(is_alpha(alpha)); - // ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF). - return ((c & 0xDF) == (alpha & 0xDF)); -} - -// https://en.cppreference.com/w/cpp/string/byte/isxdigit -// isdigit and isxdigit are the only standard narrow character classification -// functions that are not affected by the currently installed C locale. although -// some implementations (e.g. Microsoft in 1252 codepage) may classify -// additional single-byte characters as digits. -inline bool is_digit(char c) { return check_ascii_range(c, '0', '9'); } - -inline bool is_xdigit(char c) { - // Replace by look-up table. - return is_digit(c) || check_ascii_range(c & 0xDF, 'a' & 0xDF, 'f' & 0xDF); -} - -// Case-insensitive isalnum -inline bool is_alnum(char c) { return is_alpha(c) || is_digit(c); } - -inline char CharToUpper(char c) { - return static_cast<char>(::toupper(static_cast<unsigned char>(c))); -} - -inline char CharToLower(char c) { - return static_cast<char>(::tolower(static_cast<unsigned char>(c))); -} - -// @end-locale-independent functions for ASCII character set - -#ifdef FLATBUFFERS_PREFER_PRINTF -template<typename T> size_t IntToDigitCount(T t) { - size_t digit_count = 0; - // Count the sign for negative numbers - if (t < 0) digit_count++; - // Count a single 0 left of the dot for fractional numbers - if (-1 < t && t < 1) digit_count++; - // Count digits until fractional part - T eps = std::numeric_limits<float>::epsilon(); - while (t <= (-1 + eps) || (1 - eps) <= t) { - t /= 10; - digit_count++; - } - return digit_count; -} - -template<typename T> size_t NumToStringWidth(T t, int precision = 0) { - size_t string_width = IntToDigitCount(t); - // Count the dot for floating point numbers - if (precision) string_width += (precision + 1); - return string_width; -} - -template<typename T> -std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) { - size_t string_width = NumToStringWidth(t, precision); - std::string s(string_width, 0x00); - // Allow snprintf to use std::string trailing null to detect buffer overflow - snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, string_width, t); - return s; -} -#endif // FLATBUFFERS_PREFER_PRINTF - -// Convert an integer or floating point value to a string. -// In contrast to std::stringstream, "char" values are -// converted to a string of digits, and we don't use scientific notation. -template<typename T> std::string NumToString(T t) { - // clang-format off - - #ifndef FLATBUFFERS_PREFER_PRINTF - std::stringstream ss; - ss << t; - return ss.str(); - #else // FLATBUFFERS_PREFER_PRINTF - auto v = static_cast<long long>(t); - return NumToStringImplWrapper(v, "%.*lld"); - #endif // FLATBUFFERS_PREFER_PRINTF - // clang-format on -} -// Avoid char types used as character data. -template<> inline std::string NumToString<signed char>(signed char t) { - return NumToString(static_cast<int>(t)); -} -template<> inline std::string NumToString<unsigned char>(unsigned char t) { - return NumToString(static_cast<int>(t)); -} -template<> inline std::string NumToString<char>(char t) { - return NumToString(static_cast<int>(t)); -} -#if defined(FLATBUFFERS_CPP98_STL) -template<> inline std::string NumToString<long long>(long long t) { - char buf[21]; // (log((1 << 63) - 1) / log(10)) + 2 - snprintf(buf, sizeof(buf), "%lld", t); - return std::string(buf); -} - -template<> -inline std::string NumToString<unsigned long long>(unsigned long long t) { - char buf[22]; // (log((1 << 63) - 1) / log(10)) + 1 - snprintf(buf, sizeof(buf), "%llu", t); - return std::string(buf); -} -#endif // defined(FLATBUFFERS_CPP98_STL) - -// Special versions for floats/doubles. -template<typename T> std::string FloatToString(T t, int precision) { - // clang-format off - - #ifndef FLATBUFFERS_PREFER_PRINTF - // to_string() prints different numbers of digits for floats depending on - // platform and isn't available on Android, so we use stringstream - std::stringstream ss; - // Use std::fixed to suppress scientific notation. - ss << std::fixed; - // Default precision is 6, we want that to be higher for doubles. - ss << std::setprecision(precision); - ss << t; - auto s = ss.str(); - #else // FLATBUFFERS_PREFER_PRINTF - auto v = static_cast<double>(t); - auto s = NumToStringImplWrapper(v, "%0.*f", precision); - #endif // FLATBUFFERS_PREFER_PRINTF - // clang-format on - // Sadly, std::fixed turns "1" into "1.00000", so here we undo that. - auto p = s.find_last_not_of('0'); - if (p != std::string::npos) { - // Strip trailing zeroes. If it is a whole number, keep one zero. - s.resize(p + (s[p] == '.' ? 2 : 1)); - } - return s; -} - -template<> inline std::string NumToString<double>(double t) { - return FloatToString(t, 12); -} -template<> inline std::string NumToString<float>(float t) { - return FloatToString(t, 6); -} - -// Convert an integer value to a hexadecimal string. -// The returned string length is always xdigits long, prefixed by 0 digits. -// For example, IntToStringHex(0x23, 8) returns the string "00000023". -inline std::string IntToStringHex(int i, int xdigits) { - FLATBUFFERS_ASSERT(i >= 0); - // clang-format off - - #ifndef FLATBUFFERS_PREFER_PRINTF - std::stringstream ss; - ss << std::setw(xdigits) << std::setfill('0') << std::hex << std::uppercase - << i; - return ss.str(); - #else // FLATBUFFERS_PREFER_PRINTF - return NumToStringImplWrapper(i, "%.*X", xdigits); - #endif // FLATBUFFERS_PREFER_PRINTF - // clang-format on -} - -// clang-format off -// Use locale independent functions {strtod_l, strtof_l, strtoll_l, strtoull_l}. -#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && (FLATBUFFERS_LOCALE_INDEPENDENT > 0) - class ClassicLocale { - #ifdef _MSC_VER - typedef _locale_t locale_type; - #else - typedef locale_t locale_type; // POSIX.1-2008 locale_t type - #endif - ClassicLocale(); - ~ClassicLocale(); - locale_type locale_; - static ClassicLocale instance_; - public: - static locale_type Get() { return instance_.locale_; } - }; - - #ifdef _MSC_VER - #define __strtoull_impl(s, pe, b) _strtoui64_l(s, pe, b, ClassicLocale::Get()) - #define __strtoll_impl(s, pe, b) _strtoi64_l(s, pe, b, ClassicLocale::Get()) - #define __strtod_impl(s, pe) _strtod_l(s, pe, ClassicLocale::Get()) - #define __strtof_impl(s, pe) _strtof_l(s, pe, ClassicLocale::Get()) - #else - #define __strtoull_impl(s, pe, b) strtoull_l(s, pe, b, ClassicLocale::Get()) - #define __strtoll_impl(s, pe, b) strtoll_l(s, pe, b, ClassicLocale::Get()) - #define __strtod_impl(s, pe) strtod_l(s, pe, ClassicLocale::Get()) - #define __strtof_impl(s, pe) strtof_l(s, pe, ClassicLocale::Get()) - #endif -#else - #define __strtod_impl(s, pe) strtod(s, pe) - #define __strtof_impl(s, pe) static_cast<float>(strtod(s, pe)) - #ifdef _MSC_VER - #define __strtoull_impl(s, pe, b) _strtoui64(s, pe, b) - #define __strtoll_impl(s, pe, b) _strtoi64(s, pe, b) - #else - #define __strtoull_impl(s, pe, b) strtoull(s, pe, b) - #define __strtoll_impl(s, pe, b) strtoll(s, pe, b) - #endif -#endif - -inline void strtoval_impl(int64_t *val, const char *str, char **endptr, - int base) { - *val = __strtoll_impl(str, endptr, base); -} - -inline void strtoval_impl(uint64_t *val, const char *str, char **endptr, - int base) { - *val = __strtoull_impl(str, endptr, base); -} - -inline void strtoval_impl(double *val, const char *str, char **endptr) { - *val = __strtod_impl(str, endptr); -} - -// UBSAN: double to float is safe if numeric_limits<float>::is_iec559 is true. -__supress_ubsan__("float-cast-overflow") -inline void strtoval_impl(float *val, const char *str, char **endptr) { - *val = __strtof_impl(str, endptr); -} -#undef __strtoull_impl -#undef __strtoll_impl -#undef __strtod_impl -#undef __strtof_impl -// clang-format on - -// Adaptor for strtoull()/strtoll(). -// Flatbuffers accepts numbers with any count of leading zeros (-009 is -9), -// while strtoll with base=0 interprets first leading zero as octal prefix. -// In future, it is possible to add prefixed 0b0101. -// 1) Checks errno code for overflow condition (out of range). -// 2) If base <= 0, function try to detect base of number by prefix. -// -// Return value (like strtoull and strtoll, but reject partial result): -// - If successful, an integer value corresponding to the str is returned. -// - If full string conversion can't be performed, 0 is returned. -// - If the converted value falls out of range of corresponding return type, a -// range error occurs. In this case value MAX(T)/MIN(T) is returned. -template<typename T> -inline bool StringToIntegerImpl(T *val, const char *const str, - const int base = 0, - const bool check_errno = true) { - // T is int64_t or uint64_T - FLATBUFFERS_ASSERT(str); - if (base <= 0) { - auto s = str; - while (*s && !is_digit(*s)) s++; - if (s[0] == '0' && is_alpha_char(s[1], 'X')) - return StringToIntegerImpl(val, str, 16, check_errno); - // if a prefix not match, try base=10 - return StringToIntegerImpl(val, str, 10, check_errno); - } else { - if (check_errno) errno = 0; // clear thread-local errno - auto endptr = str; - strtoval_impl(val, str, const_cast<char **>(&endptr), base); - if ((*endptr != '\0') || (endptr == str)) { - *val = 0; // erase partial result - return false; // invalid string - } - // errno is out-of-range, return MAX/MIN - if (check_errno && errno) return false; - return true; - } -} - -template<typename T> -inline bool StringToFloatImpl(T *val, const char *const str) { - // Type T must be either float or double. - FLATBUFFERS_ASSERT(str && val); - auto end = str; - strtoval_impl(val, str, const_cast<char **>(&end)); - auto done = (end != str) && (*end == '\0'); - if (!done) *val = 0; // erase partial result - return done; -} - -// Convert a string to an instance of T. -// Return value (matched with StringToInteger64Impl and strtod): -// - If successful, a numeric value corresponding to the str is returned. -// - If full string conversion can't be performed, 0 is returned. -// - If the converted value falls out of range of corresponding return type, a -// range error occurs. In this case value MAX(T)/MIN(T) is returned. -template<typename T> inline bool StringToNumber(const char *s, T *val) { - // Assert on `unsigned long` and `signed long` on LP64. - // If it is necessary, it could be solved with flatbuffers::enable_if<B,T>. - static_assert(sizeof(T) < sizeof(int64_t), "unexpected type T"); - FLATBUFFERS_ASSERT(s && val); - int64_t i64; - // The errno check isn't needed, will return MAX/MIN on overflow. - if (StringToIntegerImpl(&i64, s, 0, false)) { - const int64_t max = (flatbuffers::numeric_limits<T>::max)(); - const int64_t min = flatbuffers::numeric_limits<T>::lowest(); - if (i64 > max) { - *val = static_cast<T>(max); - return false; - } - if (i64 < min) { - // For unsigned types return max to distinguish from - // "no conversion can be performed" when 0 is returned. - *val = static_cast<T>(flatbuffers::is_unsigned<T>::value ? max : min); - return false; - } - *val = static_cast<T>(i64); - return true; - } - *val = 0; - return false; -} - -template<> inline bool StringToNumber<int64_t>(const char *str, int64_t *val) { - return StringToIntegerImpl(val, str); -} - -template<> -inline bool StringToNumber<uint64_t>(const char *str, uint64_t *val) { - if (!StringToIntegerImpl(val, str)) return false; - // The strtoull accepts negative numbers: - // If the minus sign was part of the input sequence, the numeric value - // calculated from the sequence of digits is negated as if by unary minus - // in the result type, which applies unsigned integer wraparound rules. - // Fix this behaviour (except -0). - if (*val) { - auto s = str; - while (*s && !is_digit(*s)) s++; - s = (s > str) ? (s - 1) : s; // step back to one symbol - if (*s == '-') { - // For unsigned types return the max to distinguish from - // "no conversion can be performed". - *val = (flatbuffers::numeric_limits<uint64_t>::max)(); - return false; - } - } - return true; -} - -template<> inline bool StringToNumber(const char *s, float *val) { - return StringToFloatImpl(val, s); -} - -template<> inline bool StringToNumber(const char *s, double *val) { - return StringToFloatImpl(val, s); -} - -inline int64_t StringToInt(const char *s, int base = 10) { - int64_t val; - return StringToIntegerImpl(&val, s, base) ? val : 0; -} - -inline uint64_t StringToUInt(const char *s, int base = 10) { - uint64_t val; - return StringToIntegerImpl(&val, s, base) ? val : 0; -} - -typedef bool (*LoadFileFunction)(const char *filename, bool binary, - std::string *dest); -typedef bool (*FileExistsFunction)(const char *filename); - -LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function); - -FileExistsFunction SetFileExistsFunction( - FileExistsFunction file_exists_function); - -// Check if file "name" exists. -bool FileExists(const char *name); - -// Check if "name" exists and it is also a directory. -bool DirExists(const char *name); - -// Load file "name" into "buf" returning true if successful -// false otherwise. If "binary" is false data is read -// using ifstream's text mode, otherwise data is read with -// no transcoding. -bool LoadFile(const char *name, bool binary, std::string *buf); - -// Save data "buf" of length "len" bytes into a file -// "name" returning true if successful, false otherwise. -// If "binary" is false data is written using ifstream's -// text mode, otherwise data is written with no -// transcoding. -bool SaveFile(const char *name, const char *buf, size_t len, bool binary); - -// Save data "buf" into file "name" returning true if -// successful, false otherwise. If "binary" is false -// data is written using ifstream's text mode, otherwise -// data is written with no transcoding. -inline bool SaveFile(const char *name, const std::string &buf, bool binary) { - return SaveFile(name, buf.c_str(), buf.size(), binary); -} - -// Functionality for minimalistic portable path handling. - -// The functions below behave correctly regardless of whether posix ('/') or -// Windows ('/' or '\\') separators are used. - -// Any new separators inserted are always posix. -FLATBUFFERS_CONSTEXPR char kPathSeparator = '/'; - -// Returns the path with the extension, if any, removed. -std::string StripExtension(const std::string &filepath); - -// Returns the extension, if any. -std::string GetExtension(const std::string &filepath); - -// Return the last component of the path, after the last separator. -std::string StripPath(const std::string &filepath); - -// Strip the last component of the path + separator. -std::string StripFileName(const std::string &filepath); - -// Concatenates a path with a filename, regardless of whether the path -// ends in a separator or not. -std::string ConCatPathFileName(const std::string &path, - const std::string &filename); - -// Replaces any '\\' separators with '/' -std::string PosixPath(const char *path); - -// This function ensure a directory exists, by recursively -// creating dirs for any parts of the path that don't exist yet. -void EnsureDirExists(const std::string &filepath); - -// Obtains the absolute path from any other path. -// Returns the input path if the absolute path couldn't be resolved. -std::string AbsolutePath(const std::string &filepath); - -// To and from UTF-8 unicode conversion functions - -// Convert a unicode code point into a UTF-8 representation by appending it -// to a string. Returns the number of bytes generated. -inline int ToUTF8(uint32_t ucc, std::string *out) { - FLATBUFFERS_ASSERT(!(ucc & 0x80000000)); // Top bit can't be set. - // 6 possible encodings: http://en.wikipedia.org/wiki/UTF-8 - for (int i = 0; i < 6; i++) { - // Max bits this encoding can represent. - uint32_t max_bits = 6 + i * 5 + static_cast<int>(!i); - if (ucc < (1u << max_bits)) { // does it fit? - // Remaining bits not encoded in the first byte, store 6 bits each - uint32_t remain_bits = i * 6; - // Store first byte: - (*out) += static_cast<char>((0xFE << (max_bits - remain_bits)) | - (ucc >> remain_bits)); - // Store remaining bytes: - for (int j = i - 1; j >= 0; j--) { - (*out) += static_cast<char>(((ucc >> (j * 6)) & 0x3F) | 0x80); - } - return i + 1; // Return the number of bytes added. - } - } - FLATBUFFERS_ASSERT(0); // Impossible to arrive here. - return -1; -} - -// Converts whatever prefix of the incoming string corresponds to a valid -// UTF-8 sequence into a unicode code. The incoming pointer will have been -// advanced past all bytes parsed. -// returns -1 upon corrupt UTF-8 encoding (ignore the incoming pointer in -// this case). -inline int FromUTF8(const char **in) { - int len = 0; - // Count leading 1 bits. - for (int mask = 0x80; mask >= 0x04; mask >>= 1) { - if (**in & mask) { - len++; - } else { - break; - } - } - if ((static_cast<unsigned char>(**in) << len) & 0x80) - return -1; // Bit after leading 1's must be 0. - if (!len) return *(*in)++; - // UTF-8 encoded values with a length are between 2 and 4 bytes. - if (len < 2 || len > 4) { return -1; } - // Grab initial bits of the code. - int ucc = *(*in)++ & ((1 << (7 - len)) - 1); - for (int i = 0; i < len - 1; i++) { - if ((**in & 0xC0) != 0x80) return -1; // Upper bits must 1 0. - ucc <<= 6; - ucc |= *(*in)++ & 0x3F; // Grab 6 more bits of the code. - } - // UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for - // UTF-16 surrogate pairs). - if (ucc >= 0xD800 && ucc <= 0xDFFF) { return -1; } - // UTF-8 must represent code points in their shortest possible encoding. - switch (len) { - case 2: - // Two bytes of UTF-8 can represent code points from U+0080 to U+07FF. - if (ucc < 0x0080 || ucc > 0x07FF) { return -1; } - break; - case 3: - // Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF. - if (ucc < 0x0800 || ucc > 0xFFFF) { return -1; } - break; - case 4: - // Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF. - if (ucc < 0x10000 || ucc > 0x10FFFF) { return -1; } - break; - } - return ucc; -} - -#ifndef FLATBUFFERS_PREFER_PRINTF -// Wraps a string to a maximum length, inserting new lines where necessary. Any -// existing whitespace will be collapsed down to a single space. A prefix or -// suffix can be provided, which will be inserted before or after a wrapped -// line, respectively. -inline std::string WordWrap(const std::string in, size_t max_length, - const std::string wrapped_line_prefix, - const std::string wrapped_line_suffix) { - std::istringstream in_stream(in); - std::string wrapped, line, word; - - in_stream >> word; - line = word; - - while (in_stream >> word) { - if ((line.length() + 1 + word.length() + wrapped_line_suffix.length()) < - max_length) { - line += " " + word; - } else { - wrapped += line + wrapped_line_suffix + "\n"; - line = wrapped_line_prefix + word; - } - } - wrapped += line; - - return wrapped; -} -#endif // !FLATBUFFERS_PREFER_PRINTF - -inline bool EscapeString(const char *s, size_t length, std::string *_text, - bool allow_non_utf8, bool natural_utf8) { - std::string &text = *_text; - text += "\""; - for (uoffset_t i = 0; i < length; i++) { - char c = s[i]; - switch (c) { - case '\n': text += "\\n"; break; - case '\t': text += "\\t"; break; - case '\r': text += "\\r"; break; - case '\b': text += "\\b"; break; - case '\f': text += "\\f"; break; - case '\"': text += "\\\""; break; - case '\\': text += "\\\\"; break; - default: - if (c >= ' ' && c <= '~') { - text += c; - } else { - // Not printable ASCII data. Let's see if it's valid UTF-8 first: - const char *utf8 = s + i; - int ucc = FromUTF8(&utf8); - if (ucc < 0) { - if (allow_non_utf8) { - text += "\\x"; - text += IntToStringHex(static_cast<uint8_t>(c), 2); - } else { - // There are two cases here: - // - // 1) We reached here by parsing an IDL file. In that case, - // we previously checked for non-UTF-8, so we shouldn't reach - // here. - // - // 2) We reached here by someone calling GenerateText() - // on a previously-serialized flatbuffer. The data might have - // non-UTF-8 Strings, or might be corrupt. - // - // In both cases, we have to give up and inform the caller - // they have no JSON. - return false; - } - } else { - if (natural_utf8) { - // utf8 points to past all utf-8 bytes parsed - text.append(s + i, static_cast<size_t>(utf8 - s - i)); - } else if (ucc <= 0xFFFF) { - // Parses as Unicode within JSON's \uXXXX range, so use that. - text += "\\u"; - text += IntToStringHex(ucc, 4); - } else if (ucc <= 0x10FFFF) { - // Encode Unicode SMP values to a surrogate pair using two \u - // escapes. - uint32_t base = ucc - 0x10000; - auto high_surrogate = (base >> 10) + 0xD800; - auto low_surrogate = (base & 0x03FF) + 0xDC00; - text += "\\u"; - text += IntToStringHex(high_surrogate, 4); - text += "\\u"; - text += IntToStringHex(low_surrogate, 4); - } - // Skip past characters recognized. - i = static_cast<uoffset_t>(utf8 - s - 1); - } - } - break; - } - } - text += "\""; - return true; -} - -inline std::string BufferToHexText(const void *buffer, size_t buffer_size, - size_t max_length, - const std::string &wrapped_line_prefix, - const std::string &wrapped_line_suffix) { - std::string text = wrapped_line_prefix; - size_t start_offset = 0; - const char *s = reinterpret_cast<const char *>(buffer); - for (size_t i = 0; s && i < buffer_size; i++) { - // Last iteration or do we have more? - bool have_more = i + 1 < buffer_size; - text += "0x"; - text += IntToStringHex(static_cast<uint8_t>(s[i]), 2); - if (have_more) { text += ','; } - // If we have more to process and we reached max_length - if (have_more && - text.size() + wrapped_line_suffix.size() >= start_offset + max_length) { - text += wrapped_line_suffix; - text += '\n'; - start_offset = text.size(); - text += wrapped_line_prefix; - } - } - text += wrapped_line_suffix; - return text; -} - -// Remove paired quotes in a string: "text"|'text' -> text. -std::string RemoveStringQuotes(const std::string &s); - -// Change th global C-locale to locale with name <locale_name>. -// Returns an actual locale name in <_value>, useful if locale_name is "" or -// null. -bool SetGlobalTestLocale(const char *locale_name, - std::string *_value = nullptr); - -// Read (or test) a value of environment variable. -bool ReadEnvironmentVariable(const char *var_name, - std::string *_value = nullptr); - -// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs. -void SetupDefaultCRTReportMode(); - -} // namespace flatbuffers - -#endif // FLATBUFFERS_UTIL_H_ diff --git a/contrib/libs/flatbuffers/samples/monster.fbs b/contrib/libs/flatbuffers/samples/monster.fbs deleted file mode 100644 index af224512ee..0000000000 --- a/contrib/libs/flatbuffers/samples/monster.fbs +++ /dev/null @@ -1,33 +0,0 @@ -// Example IDL file for our monster's schema. - -namespace MyGame.Sample; - -enum Color:byte { Red = 0, Green, Blue = 2 } - -union Equipment { Weapon } // Optionally add more tables. - -struct Vec3 { - x:float; - y:float; - z:float; -} - -table Monster { - pos:Vec3; - mana:short = 150; - hp:short = 100; - name:string; - friendly:bool = false (deprecated); - inventory:[ubyte]; - color:Color = Blue; - weapons:[Weapon]; - equipped:Equipment; - path:[Vec3]; -} - -table Weapon { - name:string; - damage:short; -} - -root_type Monster; diff --git a/contrib/libs/flatbuffers/samples/sample_binary.cpp b/contrib/libs/flatbuffers/samples/sample_binary.cpp deleted file mode 100644 index 6bd1cdcf43..0000000000 --- a/contrib/libs/flatbuffers/samples/sample_binary.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2015 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 - * - * 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 <contrib/libs/flatbuffers/samples/monster.fbs.h> - -using namespace MyGame::Sample; - -// Example how to use FlatBuffers to create and read binary buffers. - -int main(int /*argc*/, const char * /*argv*/[]) { - // Build up a serialized buffer algorithmically: - flatbuffers::FlatBufferBuilder builder; - - // First, lets serialize some weapons for the Monster: A 'sword' and an 'axe'. - auto weapon_one_name = builder.CreateString("Sword"); - short weapon_one_damage = 3; - - auto weapon_two_name = builder.CreateString("Axe"); - short weapon_two_damage = 5; - - // Use the `CreateWeapon` shortcut to create Weapons with all fields set. - auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage); - auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage); - - // Create a FlatBuffer's `vector` from the `std::vector`. - std::vector<flatbuffers::Offset<Weapon>> weapons_vector; - weapons_vector.push_back(sword); - weapons_vector.push_back(axe); - auto weapons = builder.CreateVector(weapons_vector); - - // Second, serialize the rest of the objects needed by the Monster. - auto position = Vec3(1.0f, 2.0f, 3.0f); - - auto name = builder.CreateString("MyMonster"); - - unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - auto inventory = builder.CreateVector(inv_data, 10); - - // Shortcut for creating monster with all fields set: - auto orc = CreateMonster(builder, &position, 150, 80, name, inventory, - Color_Red, weapons, Equipment_Weapon, axe.Union()); - - builder.Finish(orc); // Serialize the root of the object. - - // We now have a FlatBuffer we can store on disk or send over a network. - - // ** file/network code goes here :) ** - // access builder.GetBufferPointer() for builder.GetSize() bytes - - // Instead, we're going to access it right away (as if we just received it). - - // Get access to the root: - auto monster = GetMonster(builder.GetBufferPointer()); - - // Get and test some scalar types from the FlatBuffer. - assert(monster->hp() == 80); - assert(monster->mana() == 150); // default - assert(monster->name()->str() == "MyMonster"); - - // Get and test a field of the FlatBuffer's `struct`. - auto pos = monster->pos(); - assert(pos); - assert(pos->z() == 3.0f); - (void)pos; - - // Get a test an element from the `inventory` FlatBuffer's `vector`. - auto inv = monster->inventory(); - assert(inv); - assert(inv->Get(9) == 9); - (void)inv; - - // Get and test the `weapons` FlatBuffers's `vector`. - std::string expected_weapon_names[] = { "Sword", "Axe" }; - short expected_weapon_damages[] = { 3, 5 }; - auto weps = monster->weapons(); - for (unsigned int i = 0; i < weps->size(); i++) { - assert(weps->Get(i)->name()->str() == expected_weapon_names[i]); - assert(weps->Get(i)->damage() == expected_weapon_damages[i]); - } - (void)expected_weapon_names; - (void)expected_weapon_damages; - - // Get and test the `Equipment` union (`equipped` field). - assert(monster->equipped_type() == Equipment_Weapon); - auto equipped = static_cast<const Weapon *>(monster->equipped()); - assert(equipped->name()->str() == "Axe"); - assert(equipped->damage() == 5); - (void)equipped; - - printf("The FlatBuffer was successfully created and verified!\n"); -} diff --git a/contrib/libs/flatbuffers/samples/ya.make b/contrib/libs/flatbuffers/samples/ya.make deleted file mode 100644 index 7855f8f461..0000000000 --- a/contrib/libs/flatbuffers/samples/ya.make +++ /dev/null @@ -1,18 +0,0 @@ -PROGRAM() - -LICENSE(Apache-2.0) - -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - -NO_UTIL() - -SRCS( - monster.fbs - sample_binary.cpp -) - -PEERDIR( - contrib/libs/flatbuffers -) - -END() diff --git a/contrib/libs/flatbuffers/src/code_generators.cpp b/contrib/libs/flatbuffers/src/code_generators.cpp deleted file mode 100644 index 745406ba95..0000000000 --- a/contrib/libs/flatbuffers/src/code_generators.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright 2016 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 - * - * 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 "flatbuffers/code_generators.h" - -#include <assert.h> - -#include <cmath> - -#include "flatbuffers/base.h" -#include "flatbuffers/util.h" - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4127) // C4127: conditional expression is constant -#endif - -namespace flatbuffers { - -void CodeWriter::operator+=(std::string text) { - if (!ignore_ident_ && !text.empty()) AppendIdent(stream_); - - while (true) { - auto begin = text.find("{{"); - if (begin == std::string::npos) { break; } - - auto end = text.find("}}"); - if (end == std::string::npos || end < begin) { break; } - - // Write all the text before the first {{ into the stream. - stream_.write(text.c_str(), begin); - - // The key is between the {{ and }}. - const std::string key = text.substr(begin + 2, end - begin - 2); - - // Find the value associated with the key. If it exists, write the - // value into the stream, otherwise write the key itself into the stream. - auto iter = value_map_.find(key); - if (iter != value_map_.end()) { - const std::string &value = iter->second; - stream_ << value; - } else { - FLATBUFFERS_ASSERT(false && "could not find key"); - stream_ << key; - } - - // Update the text to everything after the }}. - text = text.substr(end + 2); - } - if (!text.empty() && string_back(text) == '\\') { - text.pop_back(); - ignore_ident_ = true; - stream_ << text; - } else { - ignore_ident_ = false; - stream_ << text << std::endl; - } -} - -void CodeWriter::AppendIdent(std::stringstream &stream) { - int lvl = cur_ident_lvl_; - while (lvl--) { - stream.write(pad_.c_str(), static_cast<std::streamsize>(pad_.size())); - } -} - -const char *BaseGenerator::FlatBuffersGeneratedWarning() { - return "automatically generated by the FlatBuffers compiler," - " do not modify"; -} - -std::string BaseGenerator::NamespaceDir(const Parser &parser, - const std::string &path, - const Namespace &ns, - const bool dasherize) { - EnsureDirExists(path); - if (parser.opts.one_file) return path; - std::string namespace_dir = path; // Either empty or ends in separator. - auto &namespaces = ns.components; - for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { - namespace_dir += !dasherize ? *it : ToDasherizedCase(*it); - namespace_dir += kPathSeparator; - EnsureDirExists(namespace_dir); - } - return namespace_dir; -} - -std::string BaseGenerator::NamespaceDir(const Namespace &ns, - const bool dasherize) const { - return BaseGenerator::NamespaceDir(parser_, path_, ns, dasherize); -} - -std::string BaseGenerator::ToDasherizedCase(const std::string pascal_case) { - std::string dasherized_case; - char p = 0; - for (size_t i = 0; i < pascal_case.length(); i++) { - char const &c = pascal_case[i]; - if (is_alpha_upper(c)) { - if (i > 0 && p != kPathSeparator) dasherized_case += "-"; - dasherized_case += CharToLower(c); - } else { - dasherized_case += c; - } - p = c; - } - return dasherized_case; -} - -std::string BaseGenerator::FullNamespace(const char *separator, - const Namespace &ns) { - std::string namespace_name; - auto &namespaces = ns.components; - for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { - if (namespace_name.length()) namespace_name += separator; - namespace_name += *it; - } - return namespace_name; -} - -std::string BaseGenerator::LastNamespacePart(const Namespace &ns) { - if (!ns.components.empty()) - return ns.components.back(); - else - return std::string(""); -} - -// Ensure that a type is prefixed with its namespace. -std::string BaseGenerator::WrapInNameSpace(const Namespace *ns, - const std::string &name) const { - std::string qualified_name = qualifying_start_; - for (auto it = ns->components.begin(); it != ns->components.end(); ++it) - qualified_name += *it + qualifying_separator_; - return qualified_name + name; -} - -std::string BaseGenerator::WrapInNameSpace(const Definition &def) const { - return WrapInNameSpace(def.defined_namespace, def.name); -} - -std::string BaseGenerator::GetNameSpace(const Definition &def) const { - const Namespace *ns = def.defined_namespace; - if (CurrentNameSpace() == ns) return ""; - std::string qualified_name = qualifying_start_; - for (auto it = ns->components.begin(); it != ns->components.end(); ++it) { - qualified_name += *it; - if ((it + 1) != ns->components.end()) { - qualified_name += qualifying_separator_; - } - } - - return qualified_name; -} - -std::string BaseGenerator::GeneratedFileName(const std::string &path, - const std::string &file_name, - const IDLOptions &options) const { - return path + file_name + options.filename_suffix + "." + - (options.filename_extension.empty() ? default_extension_ - : options.filename_extension); -} - -// Generate a documentation comment, if available. -void GenComment(const std::vector<std::string> &dc, std::string *code_ptr, - const CommentConfig *config, const char *prefix) { - if (dc.begin() == dc.end()) { - // Don't output empty comment blocks with 0 lines of comment content. - return; - } - - std::string &code = *code_ptr; - if (config != nullptr && config->first_line != nullptr) { - code += std::string(prefix) + std::string(config->first_line) + "\n"; - } - std::string line_prefix = - std::string(prefix) + - ((config != nullptr && config->content_line_prefix != nullptr) - ? config->content_line_prefix - : "///"); - for (auto it = dc.begin(); it != dc.end(); ++it) { - code += line_prefix + *it + "\n"; - } - if (config != nullptr && config->last_line != nullptr) { - code += std::string(prefix) + std::string(config->last_line) + "\n"; - } -} - -template<typename T> -std::string FloatConstantGenerator::GenFloatConstantImpl( - const FieldDef &field) const { - const auto &constant = field.value.constant; - T v; - auto done = StringToNumber(constant.c_str(), &v); - FLATBUFFERS_ASSERT(done); - if (done) { -#if (!defined(_MSC_VER) || (_MSC_VER >= 1800)) - if (std::isnan(v)) return NaN(v); - if (std::isinf(v)) return Inf(v); -#endif - return Value(v, constant); - } - return "#"; // compile time error -} - -std::string FloatConstantGenerator::GenFloatConstant( - const FieldDef &field) const { - switch (field.value.type.base_type) { - case BASE_TYPE_FLOAT: return GenFloatConstantImpl<float>(field); - case BASE_TYPE_DOUBLE: return GenFloatConstantImpl<double>(field); - default: { - FLATBUFFERS_ASSERT(false); - return "INVALID_BASE_TYPE"; - } - }; -} - -TypedFloatConstantGenerator::TypedFloatConstantGenerator( - const char *double_prefix, const char *single_prefix, - const char *nan_number, const char *pos_inf_number, - const char *neg_inf_number) - : double_prefix_(double_prefix), - single_prefix_(single_prefix), - nan_number_(nan_number), - pos_inf_number_(pos_inf_number), - neg_inf_number_(neg_inf_number) {} - -std::string TypedFloatConstantGenerator::MakeNaN( - const std::string &prefix) const { - return prefix + nan_number_; -} -std::string TypedFloatConstantGenerator::MakeInf( - bool neg, const std::string &prefix) const { - if (neg) - return !neg_inf_number_.empty() ? (prefix + neg_inf_number_) - : ("-" + prefix + pos_inf_number_); - else - return prefix + pos_inf_number_; -} - -std::string TypedFloatConstantGenerator::Value(double v, - const std::string &src) const { - (void)v; - return src; -} - -std::string TypedFloatConstantGenerator::Inf(double v) const { - return MakeInf(v < 0, double_prefix_); -} - -std::string TypedFloatConstantGenerator::NaN(double v) const { - (void)v; - return MakeNaN(double_prefix_); -} - -std::string TypedFloatConstantGenerator::Value(float v, - const std::string &src) const { - (void)v; - return src + "f"; -} - -std::string TypedFloatConstantGenerator::Inf(float v) const { - return MakeInf(v < 0, single_prefix_); -} - -std::string TypedFloatConstantGenerator::NaN(float v) const { - (void)v; - return MakeNaN(single_prefix_); -} - -SimpleFloatConstantGenerator::SimpleFloatConstantGenerator( - const char *nan_number, const char *pos_inf_number, - const char *neg_inf_number) - : nan_number_(nan_number), - pos_inf_number_(pos_inf_number), - neg_inf_number_(neg_inf_number) {} - -std::string SimpleFloatConstantGenerator::Value(double v, - const std::string &src) const { - (void)v; - return src; -} - -std::string SimpleFloatConstantGenerator::Inf(double v) const { - return (v < 0) ? neg_inf_number_ : pos_inf_number_; -} - -std::string SimpleFloatConstantGenerator::NaN(double v) const { - (void)v; - return nan_number_; -} - -std::string SimpleFloatConstantGenerator::Value(float v, - const std::string &src) const { - return this->Value(static_cast<double>(v), src); -} - -std::string SimpleFloatConstantGenerator::Inf(float v) const { - return this->Inf(static_cast<double>(v)); -} - -std::string SimpleFloatConstantGenerator::NaN(float v) const { - return this->NaN(static_cast<double>(v)); -} - -std::string JavaCSharpMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name) { - FLATBUFFERS_ASSERT(parser.opts.lang == IDLOptions::kJava || - parser.opts.lang == IDLOptions::kCSharp); - - std::string file_extension = - (parser.opts.lang == IDLOptions::kJava) ? ".java" : ".cs"; - - std::string make_rule; - - for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end(); - ++it) { - auto &enum_def = **it; - if (!make_rule.empty()) make_rule += " "; - std::string directory = - BaseGenerator::NamespaceDir(parser, path, *enum_def.defined_namespace); - make_rule += directory + enum_def.name + file_extension; - } - - for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end(); - ++it) { - auto &struct_def = **it; - if (!make_rule.empty()) make_rule += " "; - std::string directory = BaseGenerator::NamespaceDir( - parser, path, *struct_def.defined_namespace); - make_rule += directory + struct_def.name + file_extension; - } - - make_rule += ": "; - auto included_files = parser.GetIncludedFilesRecursive(file_name); - for (auto it = included_files.begin(); it != included_files.end(); ++it) { - make_rule += " " + *it; - } - return make_rule; -} - -std::string BinaryFileName(const Parser &parser, const std::string &path, - const std::string &file_name) { - auto ext = parser.file_extension_.length() ? parser.file_extension_ : "bin"; - return path + file_name + "." + ext; -} - -bool GenerateBinary(const Parser &parser, const std::string &path, - const std::string &file_name) { - if (parser.opts.use_flexbuffers) { - auto data_vec = parser.flex_builder_.GetBuffer(); - auto data_ptr = reinterpret_cast<char *>(data(data_vec)); - return !parser.flex_builder_.GetSize() || - flatbuffers::SaveFile( - BinaryFileName(parser, path, file_name).c_str(), data_ptr, - parser.flex_builder_.GetSize(), true); - } - return !parser.builder_.GetSize() || - flatbuffers::SaveFile( - BinaryFileName(parser, path, file_name).c_str(), - reinterpret_cast<char *>(parser.builder_.GetBufferPointer()), - parser.builder_.GetSize(), true); -} - -std::string BinaryMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name) { - if (!parser.builder_.GetSize()) return ""; - std::string filebase = - flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); - std::string make_rule = - BinaryFileName(parser, path, filebase) + ": " + file_name; - auto included_files = - parser.GetIncludedFilesRecursive(parser.root_struct_def_->file); - for (auto it = included_files.begin(); it != included_files.end(); ++it) { - make_rule += " " + *it; - } - return make_rule; -} - -} // namespace flatbuffers - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif diff --git a/contrib/libs/flatbuffers/src/flatc.cpp b/contrib/libs/flatbuffers/src/flatc.cpp deleted file mode 100644 index 221b88676d..0000000000 --- a/contrib/libs/flatbuffers/src/flatc.cpp +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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 "flatbuffers/flatc.h" - -#include <list> - -namespace flatbuffers { - -const char *FLATC_VERSION() { return FLATBUFFERS_VERSION(); } - -void FlatCompiler::ParseFile( - flatbuffers::Parser &parser, const std::string &filename, - const std::string &contents, - std::vector<const char *> &include_directories) const { - auto local_include_directory = flatbuffers::StripFileName(filename); - include_directories.push_back(local_include_directory.c_str()); - include_directories.push_back(nullptr); - if (!parser.Parse(contents.c_str(), &include_directories[0], - filename.c_str())) { - Error(parser.error_, false, false); - } - if (!parser.error_.empty()) { Warn(parser.error_, false); } - include_directories.pop_back(); - include_directories.pop_back(); -} - -void FlatCompiler::LoadBinarySchema(flatbuffers::Parser &parser, - const std::string &filename, - const std::string &contents) { - if (!parser.Deserialize(reinterpret_cast<const uint8_t *>(contents.c_str()), - contents.size())) { - Error("failed to load binary schema: " + filename, false, false); - } -} - -void FlatCompiler::Warn(const std::string &warn, bool show_exe_name) const { - params_.warn_fn(this, warn, show_exe_name); -} - -void FlatCompiler::Error(const std::string &err, bool usage, - bool show_exe_name) const { - params_.error_fn(this, err, usage, show_exe_name); -} - -std::string FlatCompiler::GetUsageString(const char *program_name) const { - std::stringstream ss; - ss << "Usage: " << program_name << " [OPTION]... FILE... [-- FILE...]\n"; - for (size_t i = 0; i < params_.num_generators; ++i) { - const Generator &g = params_.generators[i]; - - std::stringstream full_name; - full_name << std::setw(16) << std::left << g.generator_opt_long; - const char *name = g.generator_opt_short ? g.generator_opt_short : " "; - const char *help = g.generator_help; - - ss << " " << full_name.str() << " " << name << " " << help << ".\n"; - } - // clang-format off - - // Output width - // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 - ss << - " -o PATH Prefix PATH to all generated files.\n" - " -I PATH Search for includes in the specified path.\n" - " -M Print make rules for generated files.\n" - " --version Print the version number of flatc and exit.\n" - " --strict-json Strict JSON: field names must be / will be quoted,\n" - " no trailing commas in tables/vectors.\n" - " --allow-non-utf8 Pass non-UTF-8 input through parser and emit nonstandard\n" - " \\x escapes in JSON. (Default is to raise parse error on\n" - " non-UTF-8 input.)\n" - " --natural-utf8 Output strings with UTF-8 as human-readable strings.\n" - " By default, UTF-8 characters are printed as \\uXXXX escapes.\n" - " --defaults-json Output fields whose value is the default when\n" - " writing JSON\n" - " --unknown-json Allow fields in JSON that are not defined in the\n" - " schema. These fields will be discared when generating\n" - " binaries.\n" - " --no-prefix Don\'t prefix enum values with the enum type in C++.\n" - " --scoped-enums Use C++11 style scoped and strongly typed enums.\n" - " also implies --no-prefix.\n" - " --gen-includes (deprecated), this is the default behavior.\n" - " If the original behavior is required (no include\n" - " statements) use --no-includes.\n" - " --no-includes Don\'t generate include statements for included\n" - " schemas the generated file depends on (C++ / Python).\n" - " --gen-mutable Generate accessors that can mutate buffers in-place.\n" - " --gen-onefile Generate single output file for C# and Go.\n" - " --gen-name-strings Generate type name functions for C++ and Rust.\n" - " --gen-object-api Generate an additional object-based API.\n" - " --gen-compare Generate operator== for object-based API types.\n" - " --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n" - " --java-checkerframe work Add @Pure for Java.\n" - " --gen-generated Add @Generated annotation for Java\n" - " --gen-jvmstatic Add @JvmStatic annotation for Kotlin methods\n" - " in companion object for interop from Java to Kotlin.\n" - " --gen-all Generate not just code for the current schema files,\n" - " but for all files it includes as well.\n" - " If the language uses a single file for output (by default\n" - " the case for C++ and JS), all code will end up in this one\n" - " file.\n" - " --cpp-include Adds an #include in generated file.\n" - " --cpp-ptr-type T Set object API pointer type (default std::unique_ptr).\n" - " --cpp-str-type T Set object API string type (default std::string).\n" - " T::c_str(), T::length() and T::empty() must be supported.\n" - " The custom type also needs to be constructible from std::string\n" - " (see the --cpp-str-flex-ctor option to change this behavior).\n" - " --cpp-str-flex-ctor Don't construct custom string types by passing std::string\n" - " from Flatbuffers, but (char* + length).\n" - " --cpp-std CPP_STD Generate a C++ code using features of selected C++ standard.\n" - " Supported CPP_STD values:\n" - " * 'c++0x' - generate code compatible with old compilers;\n" - " * 'c++11' - use C++11 code generator (default);\n" - " * 'c++17' - use C++17 features in generated code (experimental).\n" - " --cpp-static-reflection When using C++17, generate extra code to provide compile-time\n" - " (static) reflection of Flatbuffers types. Requires --cpp-std\n" - " to be \"c++17\" or higher.\n" - " --object-prefix Customise class prefix for C++ object-based API.\n" - " --object-suffix Customise class suffix for C++ object-based API.\n" - " Default value is \"T\".\n" - " --go-namespace Generate the overriding namespace in Golang.\n" - " --go-import Generate the overriding import for flatbuffers in Golang\n" - " (default is \"github.com/google/flatbuffers/go\").\n" - " --raw-binary Allow binaries without file_identifier to be read.\n" - " This may crash flatc given a mismatched schema.\n" - " --size-prefixed Input binaries are size prefixed buffers.\n" - " --proto Input is a .proto, translate to .fbs.\n" - " --proto-namespace-suffix Add this namespace to any flatbuffers generated\n" - " SUFFIX from protobufs.\n" - " --oneof-union Translate .proto oneofs to flatbuffer unions.\n" - " --grpc Generate GRPC interfaces for the specified languages.\n" - " --schema Serialize schemas instead of JSON (use with -b).\n" - " --bfbs-comments Add doc comments to the binary schema files.\n" - " --bfbs-builtins Add builtin attributes to the binary schema files.\n" - " --bfbs-gen-embed Generate code to embed the bfbs schema to the source.\n" - " --conform FILE Specify a schema the following schemas should be\n" - " an evolution of. Gives errors if not.\n" - " --conform-includes Include path for the schema given with --conform PATH\n" - " --filename-suffix The suffix appended to the generated file names.\n" - " Default is '_generated'.\n" - " --filename-ext The extension appended to the generated file names.\n" - " Default is language-specific (e.g., '.h' for C++)\n" - " --include-prefix Prefix this path to any generated include statements.\n" - " PATH\n" - " --keep-prefix Keep original prefix of schema include statement.\n" - " --reflect-types Add minimal type reflection to code generation.\n" - " --reflect-names Add minimal type/name reflection.\n" - " --root-type T Select or override the default root_type\n" - " --require-explicit-ids When parsing schemas, require explicit ids (id: x).\n" - " --force-defaults Emit default values in binary output from JSON\n" - " --force-empty When serializing from object API representation,\n" - " force strings and vectors to empty rather than null.\n" - " --force-empty-vectors When serializing from object API representation,\n" - " force vectors to empty rather than null.\n" - " --flexbuffers Used with \"binary\" and \"json\" options, it generates\n" - " data using schema-less FlexBuffers.\n" - " --no-warnings Inhibit all warning messages.\n" - "FILEs may be schemas (must end in .fbs), binary schemas (must end in .bfbs),\n" - "or JSON files (conforming to preceding schema). FILEs after the -- must be\n" - "binary flatbuffer format files.\n" - "Output files are named using the base file name of the input,\n" - "and written to the current directory or the path given by -o.\n" - "example: " << program_name << " -c -b schema1.fbs schema2.fbs data.json\n"; - // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 - // clang-format on - return ss.str(); -} - -int FlatCompiler::Compile(int argc, const char **argv) { - if (params_.generators == nullptr || params_.num_generators == 0) { - return 0; - } - - flatbuffers::IDLOptions opts; - std::string output_path; - - bool any_generator = false; - bool print_make_rules = false; - bool raw_binary = false; - bool schema_binary = false; - bool grpc_enabled = false; - std::vector<std::string> filenames; - std::list<std::string> include_directories_storage; - std::vector<const char *> include_directories; - std::vector<const char *> conform_include_directories; - std::vector<bool> generator_enabled(params_.num_generators, false); - size_t binary_files_from = std::numeric_limits<size_t>::max(); - std::string conform_to_schema; - - for (int argi = 0; argi < argc; argi++) { - std::string arg = argv[argi]; - if (arg[0] == '-') { - if (filenames.size() && arg[1] != '-') - Error("invalid option location: " + arg, true); - if (arg == "-o") { - if (++argi >= argc) Error("missing path following: " + arg, true); - output_path = flatbuffers::ConCatPathFileName( - flatbuffers::PosixPath(argv[argi]), ""); - } else if (arg == "-I") { - if (++argi >= argc) Error("missing path following: " + arg, true); - include_directories_storage.push_back( - flatbuffers::PosixPath(argv[argi])); - include_directories.push_back( - include_directories_storage.back().c_str()); - } else if (arg == "--conform") { - if (++argi >= argc) Error("missing path following: " + arg, true); - conform_to_schema = flatbuffers::PosixPath(argv[argi]); - } else if (arg == "--conform-includes") { - if (++argi >= argc) Error("missing path following: " + arg, true); - include_directories_storage.push_back( - flatbuffers::PosixPath(argv[argi])); - conform_include_directories.push_back( - include_directories_storage.back().c_str()); - } else if (arg == "--include-prefix") { - if (++argi >= argc) Error("missing path following: " + arg, true); - opts.include_prefix = flatbuffers::ConCatPathFileName( - flatbuffers::PosixPath(argv[argi]), ""); - } else if (arg == "--keep-prefix") { - opts.keep_include_path = true; - } else if (arg == "--strict-json") { - opts.strict_json = true; - } else if (arg == "--allow-non-utf8") { - opts.allow_non_utf8 = true; - } else if (arg == "--natural-utf8") { - opts.natural_utf8 = true; - } else if (arg == "--go-namespace") { - if (++argi >= argc) Error("missing golang namespace" + arg, true); - opts.go_namespace = argv[argi]; - } else if (arg == "--go-import") { - if (++argi >= argc) Error("missing golang import" + arg, true); - opts.go_import = argv[argi]; - } else if (arg == "--defaults-json") { - opts.output_default_scalars_in_json = true; - } else if (arg == "--unknown-json") { - opts.skip_unexpected_fields_in_json = true; - } else if (arg == "--no-prefix") { - opts.prefixed_enums = false; - } else if (arg == "--scoped-enums") { - opts.prefixed_enums = false; - opts.scoped_enums = true; - } else if (arg == "--no-union-value-namespacing") { - opts.union_value_namespacing = false; - } else if (arg == "--gen-mutable") { - opts.mutable_buffer = true; - } else if (arg == "--gen-name-strings") { - opts.generate_name_strings = true; - } else if (arg == "--gen-object-api") { - opts.generate_object_based_api = true; - } else if (arg == "--gen-compare") { - opts.gen_compare = true; - } else if (arg == "--cpp-include") { - if (++argi >= argc) Error("missing include following: " + arg, true); - opts.cpp_includes.push_back(argv[argi]); - } else if (arg == "--cpp-ptr-type") { - if (++argi >= argc) Error("missing type following: " + arg, true); - opts.cpp_object_api_pointer_type = argv[argi]; - } else if (arg == "--cpp-str-type") { - if (++argi >= argc) Error("missing type following: " + arg, true); - opts.cpp_object_api_string_type = argv[argi]; - } else if (arg == "--cpp-str-flex-ctor") { - opts.cpp_object_api_string_flexible_constructor = true; - } else if (arg == "--no-cpp-direct-copy") { - opts.cpp_direct_copy = false; - } else if (arg == "--gen-nullable") { - opts.gen_nullable = true; - } else if (arg == "--java-checkerframework") { - opts.java_checkerframework = true; - } else if (arg == "--gen-generated") { - opts.gen_generated = true; - } else if (arg == "--object-prefix") { - if (++argi >= argc) Error("missing prefix following: " + arg, true); - opts.object_prefix = argv[argi]; - } else if (arg == "--object-suffix") { - if (++argi >= argc) Error("missing suffix following: " + arg, true); - opts.object_suffix = argv[argi]; - } else if (arg == "--gen-all") { - opts.generate_all = true; - opts.include_dependence_headers = false; - } else if (arg == "--gen-includes") { - // Deprecated, remove this option some time in the future. - Warn("warning: --gen-includes is deprecated (it is now default)\n"); - } else if (arg == "--no-includes") { - opts.include_dependence_headers = false; - } else if (arg == "--gen-onefile") { - opts.one_file = true; - } else if (arg == "--raw-binary") { - raw_binary = true; - } else if (arg == "--size-prefixed") { - opts.size_prefixed = true; - } else if (arg == "--") { // Separator between text and binary inputs. - binary_files_from = filenames.size(); - } else if (arg == "--proto") { - opts.proto_mode = true; - } else if (arg == "--proto-namespace-suffix") { - if (++argi >= argc) Error("missing namespace suffix" + arg, true); - opts.proto_namespace_suffix = argv[argi]; - } else if (arg == "--oneof-union") { - opts.proto_oneof_union = true; - } else if (arg == "--schema") { - schema_binary = true; - } else if (arg == "-M") { - print_make_rules = true; - } else if (arg == "--version") { - printf("flatc version %s\n", FLATC_VERSION()); - exit(0); - } else if (arg == "--grpc") { - grpc_enabled = true; - } else if (arg == "--bfbs-comments") { - opts.binary_schema_comments = true; - } else if (arg == "--bfbs-builtins") { - opts.binary_schema_builtins = true; - } else if (arg == "--bfbs-gen-embed") { - opts.binary_schema_gen_embed = true; - } else if (arg == "--reflect-types") { - opts.mini_reflect = IDLOptions::kTypes; - } else if (arg == "--reflect-names") { - opts.mini_reflect = IDLOptions::kTypesAndNames; - } else if (arg == "--require-explicit-ids") { - opts.require_explicit_ids = true; - } else if (arg == "--root-type") { - if (++argi >= argc) Error("missing type following: " + arg, true); - opts.root_type = argv[argi]; - } else if (arg == "--filename-suffix") { - if (++argi >= argc) Error("missing filename suffix: " + arg, true); - opts.filename_suffix = argv[argi]; - } else if (arg == "--filename-ext") { - if (++argi >= argc) Error("missing filename extension: " + arg, true); - opts.filename_extension = argv[argi]; - } else if (arg == "--force-defaults") { - opts.force_defaults = true; - } else if (arg == "--force-empty") { - opts.set_empty_strings_to_null = false; - opts.set_empty_vectors_to_null = false; - } else if (arg == "--force-empty-vectors") { - opts.set_empty_vectors_to_null = false; - } else if (arg == "--java-primitive-has-method") { - opts.java_primitive_has_method = true; - } else if (arg == "--cs-gen-json-serializer") { - opts.cs_gen_json_serializer = true; - } else if (arg == "--flexbuffers") { - opts.use_flexbuffers = true; - } else if (arg == "--gen-jvmstatic") { - opts.gen_jvmstatic = true; - } else if (arg == "--no-warnings") { - opts.no_warnings = true; - } else if (arg == "--cpp-std") { - if (++argi >= argc) - Error("missing C++ standard specification" + arg, true); - opts.cpp_std = argv[argi]; - } else if (arg.rfind("--cpp-std=", 0) == 0) { - opts.cpp_std = arg.substr(std::string("--cpp-std=").size()); - } else if (arg == "--cpp-static-reflection") { - opts.cpp_static_reflection = true; - } else { - for (size_t i = 0; i < params_.num_generators; ++i) { - if (arg == params_.generators[i].generator_opt_long || - (params_.generators[i].generator_opt_short && - arg == params_.generators[i].generator_opt_short)) { - generator_enabled[i] = true; - any_generator = true; - opts.lang_to_generate |= params_.generators[i].lang; - goto found; - } - } - Error("unknown commandline argument: " + arg, true); - found:; - } - } else { - filenames.push_back(flatbuffers::PosixPath(argv[argi])); - } - } - - if (!filenames.size()) Error("missing input files", false, true); - - if (opts.proto_mode) { - if (any_generator) - Error("cannot generate code directly from .proto files", true); - } else if (!any_generator && conform_to_schema.empty()) { - Error("no options: specify at least one generator.", true); - } - - flatbuffers::Parser conform_parser; - if (!conform_to_schema.empty()) { - std::string contents; - if (!flatbuffers::LoadFile(conform_to_schema.c_str(), true, &contents)) - Error("unable to load schema: " + conform_to_schema); - - if (flatbuffers::GetExtension(conform_to_schema) == - reflection::SchemaExtension()) { - LoadBinarySchema(conform_parser, conform_to_schema, contents); - } else { - ParseFile(conform_parser, conform_to_schema, contents, - conform_include_directories); - } - } - - std::unique_ptr<flatbuffers::Parser> parser(new flatbuffers::Parser(opts)); - - for (auto file_it = filenames.begin(); file_it != filenames.end(); - ++file_it) { - auto &filename = *file_it; - std::string contents; - if (!flatbuffers::LoadFile(filename.c_str(), true, &contents)) - Error("unable to load file: " + filename); - - bool is_binary = - static_cast<size_t>(file_it - filenames.begin()) >= binary_files_from; - auto ext = flatbuffers::GetExtension(filename); - auto is_schema = ext == "fbs" || ext == "proto"; - auto is_binary_schema = ext == reflection::SchemaExtension(); - if (is_binary) { - parser->builder_.Clear(); - parser->builder_.PushFlatBuffer( - reinterpret_cast<const uint8_t *>(contents.c_str()), - contents.length()); - if (!raw_binary) { - // Generally reading binaries that do not correspond to the schema - // will crash, and sadly there's no way around that when the binary - // does not contain a file identifier. - // We'd expect that typically any binary used as a file would have - // such an identifier, so by default we require them to match. - if (!parser->file_identifier_.length()) { - Error("current schema has no file_identifier: cannot test if \"" + - filename + - "\" matches the schema, use --raw-binary to read this file" - " anyway."); - } else if (!flatbuffers::BufferHasIdentifier( - contents.c_str(), parser->file_identifier_.c_str(), - opts.size_prefixed)) { - Error("binary \"" + filename + - "\" does not have expected file_identifier \"" + - parser->file_identifier_ + - "\", use --raw-binary to read this file anyway."); - } - } - } else { - // Check if file contains 0 bytes. - if (!opts.use_flexbuffers && !is_binary_schema && - contents.length() != strlen(contents.c_str())) { - Error("input file appears to be binary: " + filename, true); - } - if (is_schema) { - // If we're processing multiple schemas, make sure to start each - // one from scratch. If it depends on previous schemas it must do - // so explicitly using an include. - parser.reset(new flatbuffers::Parser(opts)); - } - if (is_binary_schema) { - LoadBinarySchema(*parser.get(), filename, contents); - } - if (opts.use_flexbuffers) { - if (opts.lang_to_generate == IDLOptions::kJson) { - parser->flex_root_ = flexbuffers::GetRoot( - reinterpret_cast<const uint8_t *>(contents.c_str()), - contents.size()); - } else { - parser->flex_builder_.Clear(); - ParseFile(*parser.get(), filename, contents, include_directories); - } - } else { - ParseFile(*parser.get(), filename, contents, include_directories); - if (!is_schema && !parser->builder_.GetSize()) { - // If a file doesn't end in .fbs, it must be json/binary. Ensure we - // didn't just parse a schema with a different extension. - Error("input file is neither json nor a .fbs (schema) file: " + - filename, - true); - } - } - if ((is_schema || is_binary_schema) && !conform_to_schema.empty()) { - auto err = parser->ConformTo(conform_parser); - if (!err.empty()) Error("schemas don\'t conform: " + err); - } - if (schema_binary || opts.binary_schema_gen_embed) { - parser->Serialize(); - } - if (schema_binary) { - parser->file_extension_ = reflection::SchemaExtension(); - } - } - - std::string filebase = - flatbuffers::StripPath(flatbuffers::StripExtension(filename)); - - for (size_t i = 0; i < params_.num_generators; ++i) { - parser->opts.lang = params_.generators[i].lang; - if (generator_enabled[i]) { - if (!print_make_rules) { - flatbuffers::EnsureDirExists(output_path); - if ((!params_.generators[i].schema_only || - (is_schema || is_binary_schema)) && - !params_.generators[i].generate(*parser.get(), output_path, - filebase)) { - Error(std::string("Unable to generate ") + - params_.generators[i].lang_name + " for " + filebase); - } - } else { - if (params_.generators[i].make_rule == nullptr) { - Error(std::string("Cannot generate make rule for ") + - params_.generators[i].lang_name); - } else { - std::string make_rule = params_.generators[i].make_rule( - *parser.get(), output_path, filename); - if (!make_rule.empty()) - printf("%s\n", - flatbuffers::WordWrap(make_rule, 80, " ", " \\").c_str()); - } - } - if (grpc_enabled) { - if (params_.generators[i].generateGRPC != nullptr) { - if (!params_.generators[i].generateGRPC(*parser.get(), output_path, - filebase)) { - Error(std::string("Unable to generate GRPC interface for") + - params_.generators[i].lang_name); - } - } else { - Warn(std::string("GRPC interface generator not implemented for ") + - params_.generators[i].lang_name); - } - } - } - } - - if (!opts.root_type.empty()) { - if (!parser->SetRootType(opts.root_type.c_str())) - Error("unknown root type: " + opts.root_type); - else if (parser->root_struct_def_->fixed) - Error("root type must be a table"); - } - - if (opts.proto_mode) GenerateFBS(*parser.get(), output_path, filebase); - - // We do not want to generate code for the definitions in this file - // in any files coming up next. - parser->MarkGenerated(); - } - return 0; -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/flatc_main.cpp b/contrib/libs/flatbuffers/src/flatc_main.cpp deleted file mode 100644 index 31ccbc7185..0000000000 --- a/contrib/libs/flatbuffers/src/flatc_main.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2017 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 - * - * 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 "flatbuffers/flatc.h" -#include "flatbuffers/util.h" - -static const char *g_program_name = nullptr; - -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); } - printf("warning: %s\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); } - printf("error: %s\n", err.c_str()); - if (usage && flatc) { - printf("%s", flatc->GetUsageString(g_program_name).c_str()); - } - exit(1); -} - -namespace flatbuffers { -void LogCompilerWarn(const std::string &warn) { - Warn(static_cast<const flatbuffers::FlatCompiler *>(nullptr), warn, true); -} -void LogCompilerError(const std::string &err) { - Error(static_cast<const flatbuffers::FlatCompiler *>(nullptr), err, false, - true); -} -} // namespace flatbuffers - -int main(int argc, const char *argv[]) { - // Prevent Appveyor-CI hangs. - flatbuffers::SetupDefaultCRTReportMode(); - - g_program_name = argv[0]; - - const flatbuffers::FlatCompiler::Generator generators[] = { - { flatbuffers::GenerateBinary, "-b", "--binary", "binary", false, nullptr, - flatbuffers::IDLOptions::kBinary, - "Generate wire format binaries for any data definitions", - flatbuffers::BinaryMakeRule }, - { flatbuffers::GenerateTextFile, "-t", "--json", "text", false, nullptr, - flatbuffers::IDLOptions::kJson, - "Generate text output for any data definitions", - flatbuffers::TextMakeRule }, - { flatbuffers::GenerateCPP, "-c", "--cpp", "C++", true, - flatbuffers::GenerateCppGRPC, flatbuffers::IDLOptions::kCpp, - "Generate C++ headers for tables/structs", flatbuffers::CPPMakeRule }, - { flatbuffers::GenerateGo, "-g", "--go", "Go", true, - flatbuffers::GenerateGoGRPC, flatbuffers::IDLOptions::kGo, - "Generate Go files for tables/structs", nullptr }, - { flatbuffers::GenerateJava, "-j", "--java", "Java", true, - flatbuffers::GenerateJavaGRPC, flatbuffers::IDLOptions::kJava, - "Generate Java classes for tables/structs", - flatbuffers::JavaCSharpMakeRule }, - { flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr, - flatbuffers::IDLOptions::kDart, - "Generate Dart classes for tables/structs", flatbuffers::DartMakeRule }, - { flatbuffers::GenerateTS, "-T", "--ts", "TypeScript", true, - flatbuffers::GenerateTSGRPC, flatbuffers::IDLOptions::kTs, - "Generate TypeScript code for tables/structs", flatbuffers::TSMakeRule }, - { flatbuffers::GenerateCSharp, "-n", "--csharp", "C#", true, nullptr, - flatbuffers::IDLOptions::kCSharp, - "Generate C# classes for tables/structs", - flatbuffers::JavaCSharpMakeRule }, - { flatbuffers::GeneratePython, "-p", "--python", "Python", true, - flatbuffers::GeneratePythonGRPC, flatbuffers::IDLOptions::kPython, - "Generate Python files for tables/structs", nullptr }, - { flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true, - nullptr, flatbuffers::IDLOptions::kLobster, - "Generate Lobster files for tables/structs", nullptr }, - { flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr, - flatbuffers::IDLOptions::kLua, "Generate Lua files for tables/structs", - nullptr }, - { flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr, - flatbuffers::IDLOptions::kRust, "Generate Rust files for tables/structs", - flatbuffers::RustMakeRule }, - { flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr, - flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs", - nullptr }, - { flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr, - flatbuffers::IDLOptions::kKotlin, - "Generate Kotlin classes for tables/structs", nullptr }, - { flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema", - true, nullptr, flatbuffers::IDLOptions::kJsonSchema, - "Generate Json schema", nullptr }, - { flatbuffers::GenerateSwift, nullptr, "--swift", "swift", true, - flatbuffers::GenerateSwiftGRPC, flatbuffers::IDLOptions::kSwift, - "Generate Swift files for tables/structs", nullptr }, - { flatbuffers::GenerateCPPYandexMapsIter, nullptr, "--yandex-maps-iter", "C++Iter", - true, nullptr, flatbuffers::IDLOptions::kCppYandexMapsIter, - "Generate C++ template headers for tables/structs", nullptr }, - }; - - flatbuffers::FlatCompiler::InitParams params; - params.generators = generators; - params.num_generators = sizeof(generators) / sizeof(generators[0]); - params.warn_fn = Warn; - params.error_fn = Error; - - flatbuffers::FlatCompiler flatc(params); - return flatc.Compile(argc - 1, argv + 1); -} diff --git a/contrib/libs/flatbuffers/src/idl_gen_cpp.cpp b/contrib/libs/flatbuffers/src/idl_gen_cpp.cpp deleted file mode 100644 index a33697eaed..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_cpp.cpp +++ /dev/null @@ -1,3514 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include <unordered_set> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/flatc.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -// Make numerical literal with type-suffix. -// This function is only needed for C++! Other languages do not need it. -static inline std::string NumToStringCpp(std::string val, BaseType type) { - // Avoid issues with -2147483648, -9223372036854775808. - switch (type) { - case BASE_TYPE_INT: - return (val != "-2147483648") ? val : ("(-2147483647 - 1)"); - case BASE_TYPE_ULONG: return (val == "0") ? val : (val + "ULL"); - case BASE_TYPE_LONG: - if (val == "-9223372036854775808") - return "(-9223372036854775807LL - 1LL)"; - else - return (val == "0") ? val : (val + "LL"); - default: return val; - } -} - -static std::string GenIncludeGuard(const std::string &file_name, - const Namespace &name_space, - const std::string &postfix = "") { - // Generate include guard. - std::string guard = file_name; - // Remove any non-alpha-numeric characters that may appear in a filename. - struct IsAlnum { - bool operator()(char c) const { return !is_alnum(c); } - }; - guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()), - guard.end()); - guard = "FLATBUFFERS_GENERATED_" + guard; - guard += "_"; - // For further uniqueness, also add the namespace. - for (auto it = name_space.components.begin(); - it != name_space.components.end(); ++it) { - guard += *it + "_"; - } - // Anything extra to add to the guard? - if (!postfix.empty()) { guard += postfix + "_"; } - guard += "H_"; - std::transform(guard.begin(), guard.end(), guard.begin(), CharToUpper); - return guard; -} - -namespace cpp { - -enum CppStandard { CPP_STD_X0 = 0, CPP_STD_11, CPP_STD_17 }; - -// Define a style of 'struct' constructor if it has 'Array' fields. -enum GenArrayArgMode { - kArrayArgModeNone, // don't generate initialization args - kArrayArgModeSpanStatic, // generate flatbuffers::span<T,N> -}; - -// Extension of IDLOptions for cpp-generator. -struct IDLOptionsCpp : public IDLOptions { - // All fields start with 'g_' prefix to distinguish from the base IDLOptions. - CppStandard g_cpp_std; // Base version of C++ standard. - bool g_only_fixed_enums; // Generate underlaying type for all enums. - - IDLOptionsCpp(const IDLOptions &opts) - : IDLOptions(opts), g_cpp_std(CPP_STD_11), g_only_fixed_enums(true) {} -}; - -class CppGenerator : public BaseGenerator { - public: - CppGenerator(const Parser &parser, const std::string &path, - const std::string &file_name, IDLOptionsCpp opts) - : BaseGenerator(parser, path, file_name, "", "::", "h"), - cur_name_space_(nullptr), - opts_(opts), - float_const_gen_("std::numeric_limits<double>::", - "std::numeric_limits<float>::", "quiet_NaN()", - "infinity()") { - static const char *const keywords[] = { - "alignas", - "alignof", - "and", - "and_eq", - "asm", - "atomic_cancel", - "atomic_commit", - "atomic_noexcept", - "auto", - "bitand", - "bitor", - "bool", - "break", - "case", - "catch", - "char", - "char16_t", - "char32_t", - "class", - "compl", - "concept", - "const", - "constexpr", - "const_cast", - "continue", - "co_await", - "co_return", - "co_yield", - "decltype", - "default", - "delete", - "do", - "double", - "dynamic_cast", - "else", - "enum", - "explicit", - "export", - "extern", - "false", - "float", - "for", - "friend", - "goto", - "if", - "import", - "inline", - "int", - "long", - "module", - "mutable", - "namespace", - "new", - "noexcept", - "not", - "not_eq", - "nullptr", - "operator", - "or", - "or_eq", - "private", - "protected", - "public", - "register", - "reinterpret_cast", - "requires", - "return", - "short", - "signed", - "sizeof", - "static", - "static_assert", - "static_cast", - "struct", - "switch", - "synchronized", - "template", - "this", - "thread_local", - "throw", - "true", - "try", - "typedef", - "typeid", - "typename", - "union", - "unsigned", - "using", - "virtual", - "void", - "volatile", - "wchar_t", - "while", - "xor", - "xor_eq", - nullptr, - }; - for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw); - } - - void GenIncludeDependencies() { - int num_includes = 0; - if (opts_.generate_object_based_api) { - for (auto it = parser_.native_included_files_.begin(); - it != parser_.native_included_files_.end(); ++it) { - code_ += "#include \"" + *it + "\""; - num_includes++; - } - } - for (auto it = parser_.included_files_.begin(); - it != parser_.included_files_.end(); ++it) { - if (it->second.empty()) continue; - auto noext = flatbuffers::StripExtension(it->second); - auto basename = flatbuffers::StripPath(noext); - auto includeName = - GeneratedFileName(opts_.include_prefix, - opts_.keep_include_path ? noext : basename, opts_); - code_ += "#include \"" + includeName + "\""; - num_includes++; - } - if (num_includes) code_ += ""; - } - - void GenExtraIncludes() { - for (std::size_t i = 0; i < opts_.cpp_includes.size(); ++i) { - code_ += "#include \"" + opts_.cpp_includes[i] + "\""; - } - if (!opts_.cpp_includes.empty()) { code_ += ""; } - } - - std::string EscapeKeyword(const std::string &name) const { - return keywords_.find(name) == keywords_.end() ? name : name + "_"; - } - - std::string Name(const Definition &def) const { - return EscapeKeyword(def.name); - } - - std::string Name(const EnumVal &ev) const { return EscapeKeyword(ev.name); } - - bool generate_bfbs_embed() { - code_.Clear(); - code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; - - // If we don't have a root struct definition, - if (!parser_.root_struct_def_) { - // put a comment in the output why there is no code generated. - code_ += "// Binary schema not generated, no root struct found"; - } else { - auto &struct_def = *parser_.root_struct_def_; - const auto include_guard = - GenIncludeGuard(file_name_, *struct_def.defined_namespace, "bfbs"); - - code_ += "#ifndef " + include_guard; - code_ += "#define " + include_guard; - code_ += ""; - if (parser_.opts.gen_nullable) { - code_ += "#pragma clang system_header\n\n"; - } - - SetNameSpace(struct_def.defined_namespace); - auto name = Name(struct_def); - code_.SetValue("STRUCT_NAME", name); - - // Create code to return the binary schema data. - auto binary_schema_hex_text = - BufferToHexText(parser_.builder_.GetBufferPointer(), - parser_.builder_.GetSize(), 105, " ", ""); - - code_ += "struct {{STRUCT_NAME}}BinarySchema {"; - code_ += " static const uint8_t *data() {"; - code_ += " // Buffer containing the binary schema."; - code_ += " static const uint8_t bfbsData[" + - NumToString(parser_.builder_.GetSize()) + "] = {"; - code_ += binary_schema_hex_text; - code_ += " };"; - code_ += " return bfbsData;"; - code_ += " }"; - code_ += " static size_t size() {"; - code_ += " return " + NumToString(parser_.builder_.GetSize()) + ";"; - code_ += " }"; - code_ += " const uint8_t *begin() {"; - code_ += " return data();"; - code_ += " }"; - code_ += " const uint8_t *end() {"; - code_ += " return data() + size();"; - code_ += " }"; - code_ += "};"; - code_ += ""; - - if (cur_name_space_) SetNameSpace(nullptr); - - // Close the include guard. - code_ += "#endif // " + include_guard; - } - - // We are just adding "_bfbs" to the generated filename. - const auto file_path = - GeneratedFileName(path_, file_name_ + "_bfbs", opts_); - const auto final_code = code_.ToString(); - - return SaveFile(file_path.c_str(), final_code, false); - } - - // Iterate through all definitions we haven't generate code for (enums, - // structs, and tables) and output them to a single file. - bool generate() { - code_.Clear(); - code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; - - const auto include_guard = - GenIncludeGuard(file_name_, *parser_.current_namespace_); - code_ += "#ifndef " + include_guard; - code_ += "#define " + include_guard; - code_ += ""; - - if (opts_.gen_nullable) { code_ += "#pragma clang system_header\n\n"; } - - code_ += "#include <contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h>"; - if (parser_.uses_flexbuffers_) { - code_ += "#include <contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h>"; - } - code_ += ""; - - if (opts_.include_dependence_headers) { GenIncludeDependencies(); } - GenExtraIncludes(); - - FLATBUFFERS_ASSERT(!cur_name_space_); - - // Generate forward declarations for all structs/tables, since they may - // have circular references. - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - code_ += "struct " + Name(struct_def) + ";"; - if (!struct_def.fixed) { - code_ += "struct " + Name(struct_def) + "Builder;"; - } - if (opts_.generate_object_based_api) { - auto nativeName = NativeName(Name(struct_def), &struct_def, opts_); - if (!struct_def.fixed) { code_ += "struct " + nativeName + ";"; } - } - code_ += ""; - } - } - - // Generate forward declarations for all equal operators - if (opts_.generate_object_based_api && opts_.gen_compare) { - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - auto nativeName = NativeName(Name(struct_def), &struct_def, opts_); - code_ += "bool operator==(const " + nativeName + " &lhs, const " + - nativeName + " &rhs);"; - code_ += "bool operator!=(const " + nativeName + " &lhs, const " + - nativeName + " &rhs);"; - } - } - code_ += ""; - } - - // Generate preablmle code for mini reflection. - if (opts_.mini_reflect != IDLOptions::kNone) { - // To break cyclic dependencies, first pre-declare all tables/structs. - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - GenMiniReflectPre(&struct_def); - } - } - } - - // Generate code for all the enum declarations. - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - const auto &enum_def = **it; - if (!enum_def.generated) { - SetNameSpace(enum_def.defined_namespace); - GenEnum(enum_def); - } - } - - // Generate code for all structs, then all tables. - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (struct_def.fixed && !struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - GenStruct(struct_def); - } - } - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.fixed && !struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - GenTable(struct_def); - } - } - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.fixed && !struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - GenTablePost(struct_def); - } - } - - // Generate code for union verifiers. - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - const auto &enum_def = **it; - if (enum_def.is_union && !enum_def.generated) { - SetNameSpace(enum_def.defined_namespace); - GenUnionPost(enum_def); - } - } - - // Generate code for mini reflection. - if (opts_.mini_reflect != IDLOptions::kNone) { - // Then the unions/enums that may refer to them. - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - const auto &enum_def = **it; - if (!enum_def.generated) { - SetNameSpace(enum_def.defined_namespace); - GenMiniReflect(nullptr, &enum_def); - } - } - // Then the full tables/structs. - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - GenMiniReflect(&struct_def, nullptr); - } - } - } - - // Generate convenient global helper functions: - if (parser_.root_struct_def_) { - auto &struct_def = *parser_.root_struct_def_; - SetNameSpace(struct_def.defined_namespace); - auto name = Name(struct_def); - auto qualified_name = cur_name_space_->GetFullyQualifiedName(name); - auto cpp_name = TranslateNameSpace(qualified_name); - - code_.SetValue("STRUCT_NAME", name); - code_.SetValue("CPP_NAME", cpp_name); - code_.SetValue("NULLABLE_EXT", NullableExtension()); - - // The root datatype accessor: - code_ += "inline \\"; - code_ += - "const {{CPP_NAME}} *{{NULLABLE_EXT}}Get{{STRUCT_NAME}}(const void " - "*buf) {"; - code_ += " return flatbuffers::GetRoot<{{CPP_NAME}}>(buf);"; - code_ += "}"; - code_ += ""; - - code_ += "inline \\"; - code_ += - "const {{CPP_NAME}} " - "*{{NULLABLE_EXT}}GetSizePrefixed{{STRUCT_NAME}}(const void " - "*buf) {"; - code_ += " return flatbuffers::GetSizePrefixedRoot<{{CPP_NAME}}>(buf);"; - code_ += "}"; - code_ += ""; - - if (opts_.mutable_buffer) { - code_ += "inline \\"; - code_ += "{{STRUCT_NAME}} *GetMutable{{STRUCT_NAME}}(void *buf) {"; - code_ += " return flatbuffers::GetMutableRoot<{{STRUCT_NAME}}>(buf);"; - code_ += "}"; - code_ += ""; - } - - if (parser_.file_identifier_.length()) { - // Return the identifier - code_ += "inline const char *{{STRUCT_NAME}}Identifier() {"; - code_ += " return \"" + parser_.file_identifier_ + "\";"; - code_ += "}"; - code_ += ""; - - // Check if a buffer has the identifier. - code_ += "inline \\"; - code_ += "bool {{STRUCT_NAME}}BufferHasIdentifier(const void *buf) {"; - code_ += " return flatbuffers::BufferHasIdentifier("; - code_ += " buf, {{STRUCT_NAME}}Identifier());"; - code_ += "}"; - code_ += ""; - } - - // The root verifier. - if (parser_.file_identifier_.length()) { - code_.SetValue("ID", name + "Identifier()"); - } else { - code_.SetValue("ID", "nullptr"); - } - - code_ += "inline bool Verify{{STRUCT_NAME}}Buffer("; - code_ += " flatbuffers::Verifier &verifier) {"; - code_ += " return verifier.VerifyBuffer<{{CPP_NAME}}>({{ID}});"; - code_ += "}"; - code_ += ""; - - code_ += "inline bool VerifySizePrefixed{{STRUCT_NAME}}Buffer("; - code_ += " flatbuffers::Verifier &verifier) {"; - code_ += - " return verifier.VerifySizePrefixedBuffer<{{CPP_NAME}}>({{ID}});"; - code_ += "}"; - code_ += ""; - - if (parser_.file_extension_.length()) { - // Return the extension - code_ += "inline const char *{{STRUCT_NAME}}Extension() {"; - code_ += " return \"" + parser_.file_extension_ + "\";"; - code_ += "}"; - code_ += ""; - } - - // Finish a buffer with a given root object: - code_ += "inline void Finish{{STRUCT_NAME}}Buffer("; - code_ += " flatbuffers::FlatBufferBuilder &fbb,"; - code_ += " flatbuffers::Offset<{{CPP_NAME}}> root) {"; - if (parser_.file_identifier_.length()) - code_ += " fbb.Finish(root, {{STRUCT_NAME}}Identifier());"; - else - code_ += " fbb.Finish(root);"; - code_ += "}"; - code_ += ""; - - code_ += "inline void FinishSizePrefixed{{STRUCT_NAME}}Buffer("; - code_ += " flatbuffers::FlatBufferBuilder &fbb,"; - code_ += " flatbuffers::Offset<{{CPP_NAME}}> root) {"; - if (parser_.file_identifier_.length()) - code_ += " fbb.FinishSizePrefixed(root, {{STRUCT_NAME}}Identifier());"; - else - code_ += " fbb.FinishSizePrefixed(root);"; - code_ += "}"; - code_ += ""; - - if (opts_.generate_object_based_api) { - // A convenient root unpack function. - auto native_name = WrapNativeNameInNameSpace(struct_def, opts_); - code_.SetValue("UNPACK_RETURN", - GenTypeNativePtr(native_name, nullptr, false)); - code_.SetValue("UNPACK_TYPE", - GenTypeNativePtr(native_name, nullptr, true)); - - code_ += "inline {{UNPACK_RETURN}} UnPack{{STRUCT_NAME}}("; - code_ += " const void *buf,"; - code_ += " const flatbuffers::resolver_function_t *res = nullptr) {"; - code_ += " return {{UNPACK_TYPE}}\\"; - code_ += "(Get{{STRUCT_NAME}}(buf)->UnPack(res));"; - code_ += "}"; - code_ += ""; - - code_ += "inline {{UNPACK_RETURN}} UnPackSizePrefixed{{STRUCT_NAME}}("; - code_ += " const void *buf,"; - code_ += " const flatbuffers::resolver_function_t *res = nullptr) {"; - code_ += " return {{UNPACK_TYPE}}\\"; - code_ += "(GetSizePrefixed{{STRUCT_NAME}}(buf)->UnPack(res));"; - code_ += "}"; - code_ += ""; - } - } - - if (cur_name_space_) SetNameSpace(nullptr); - - // Close the include guard. - code_ += "#endif // " + include_guard; - - const auto file_path = GeneratedFileName(path_, file_name_, opts_); - const auto final_code = code_.ToString(); - - // Save the file and optionally generate the binary schema code. - return SaveFile(file_path.c_str(), final_code, false) && - (!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed()); - } - - private: - CodeWriter code_; - - std::unordered_set<std::string> keywords_; - - // This tracks the current namespace so we can insert namespace declarations. - const Namespace *cur_name_space_; - - const IDLOptionsCpp opts_; - const TypedFloatConstantGenerator float_const_gen_; - - const Namespace *CurrentNameSpace() const { return cur_name_space_; } - - // Translates a qualified name in flatbuffer text format to the same name in - // the equivalent C++ namespace. - static std::string TranslateNameSpace(const std::string &qualified_name) { - std::string cpp_qualified_name = qualified_name; - size_t start_pos = 0; - while ((start_pos = cpp_qualified_name.find('.', start_pos)) != - std::string::npos) { - cpp_qualified_name.replace(start_pos, 1, "::"); - } - return cpp_qualified_name; - } - - bool TypeHasKey(const Type &type) { - if (type.base_type != BASE_TYPE_STRUCT) { return false; } - for (auto it = type.struct_def->fields.vec.begin(); - it != type.struct_def->fields.vec.end(); ++it) { - const auto &field = **it; - if (field.key) { return true; } - } - return false; - } - - bool VectorElementUserFacing(const Type &type) const { - return 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 = "") { - std::string text; - ::flatbuffers::GenComment(dc, &text, nullptr, prefix); - code_ += text + "\\"; - } - - // Return a C++ type from the table in idl.h - std::string GenTypeBasic(const Type &type, bool user_facing_type) const { - // clang-format off - static const char *const ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - #CTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - if (user_facing_type) { - if (type.enum_def) return WrapInNameSpace(*type.enum_def); - if (type.base_type == BASE_TYPE_BOOL) return "bool"; - } - return ctypename[type.base_type]; - } - - // Return a C++ pointer type, specialized to the actual struct/table types, - // and vector element types. - std::string GenTypePointer(const Type &type) const { - switch (type.base_type) { - case BASE_TYPE_STRING: { - return "flatbuffers::String"; - } - case BASE_TYPE_VECTOR: { - const auto type_name = GenTypeWire( - type.VectorType(), "", VectorElementUserFacing(type.VectorType())); - return "flatbuffers::Vector<" + type_name + ">"; - } - case BASE_TYPE_STRUCT: { - return WrapInNameSpace(*type.struct_def); - } - case BASE_TYPE_UNION: - // fall through - default: { - return "void"; - } - } - } - - // Return a C++ type for any type (scalar/pointer) specifically for - // building a flatbuffer. - std::string GenTypeWire(const Type &type, const char *postfix, - bool user_facing_type) const { - if (IsScalar(type.base_type)) { - return GenTypeBasic(type, user_facing_type) + postfix; - } else if (IsStruct(type)) { - return "const " + GenTypePointer(type) + " *"; - } else { - return "flatbuffers::Offset<" + GenTypePointer(type) + ">" + postfix; - } - } - - // Return a C++ type for any type (scalar/pointer) that reflects its - // serialized size. - std::string GenTypeSize(const Type &type) const { - if (IsScalar(type.base_type)) { - return GenTypeBasic(type, false); - } else if (IsStruct(type)) { - return GenTypePointer(type); - } else { - return "flatbuffers::uoffset_t"; - } - } - - std::string NullableExtension() { - return opts_.gen_nullable ? " _Nullable " : ""; - } - - static std::string NativeName(const std::string &name, const StructDef *sd, - const IDLOptions &opts) { - return sd && !sd->fixed ? opts.object_prefix + name + opts.object_suffix - : name; - } - - std::string WrapNativeNameInNameSpace(const StructDef &struct_def, - const IDLOptions &opts) { - return WrapInNameSpace(struct_def.defined_namespace, - NativeName(Name(struct_def), &struct_def, opts)); - } - - const std::string &PtrType(const FieldDef *field) { - auto attr = field ? field->attributes.Lookup("cpp_ptr_type") : nullptr; - return attr ? attr->constant : opts_.cpp_object_api_pointer_type; - } - - const std::string NativeString(const FieldDef *field) { - auto attr = field ? field->attributes.Lookup("cpp_str_type") : nullptr; - auto &ret = attr ? attr->constant : opts_.cpp_object_api_string_type; - if (ret.empty()) { return "std::string"; } - return ret; - } - - bool FlexibleStringConstructor(const FieldDef *field) { - auto attr = field - ? (field->attributes.Lookup("cpp_str_flex_ctor") != nullptr) - : false; - auto ret = attr ? attr : opts_.cpp_object_api_string_flexible_constructor; - return ret && NativeString(field) != - "std::string"; // Only for custom string types. - } - - std::string GenTypeNativePtr(const std::string &type, const FieldDef *field, - bool is_constructor) { - auto &ptr_type = PtrType(field); - if (ptr_type != "naked") { - return (ptr_type != "default_ptr_type" - ? ptr_type - : opts_.cpp_object_api_pointer_type) + - "<" + type + ">"; - } else if (is_constructor) { - return ""; - } else { - return type + " *"; - } - } - - std::string GenPtrGet(const FieldDef &field) { - auto cpp_ptr_type_get = field.attributes.Lookup("cpp_ptr_type_get"); - if (cpp_ptr_type_get) return cpp_ptr_type_get->constant; - auto &ptr_type = PtrType(&field); - return ptr_type == "naked" ? "" : ".get()"; - } - - std::string GenOptionalNull() { return "flatbuffers::nullopt"; } - - std::string GenOptionalDecl(const Type &type) { - return "flatbuffers::Optional<" + GenTypeBasic(type, true) + ">"; - } - - std::string GenTypeNative(const Type &type, bool invector, - const FieldDef &field) { - switch (type.base_type) { - case BASE_TYPE_STRING: { - return NativeString(&field); - } - case BASE_TYPE_VECTOR: { - const auto type_name = GenTypeNative(type.VectorType(), true, field); - if (type.struct_def && - type.struct_def->attributes.Lookup("native_custom_alloc")) { - auto native_custom_alloc = - type.struct_def->attributes.Lookup("native_custom_alloc"); - return "std::vector<" + type_name + "," + - native_custom_alloc->constant + "<" + type_name + ">>"; - } else - return "std::vector<" + type_name + ">"; - } - case BASE_TYPE_STRUCT: { - auto type_name = WrapInNameSpace(*type.struct_def); - 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) { - return type_name; - } else { - return GenTypeNativePtr(type_name, &field, false); - } - } else { - return GenTypeNativePtr( - WrapNativeNameInNameSpace(*type.struct_def, opts_), &field, - false); - } - } - case BASE_TYPE_UNION: { - auto type_name = WrapInNameSpace(*type.enum_def); - return type_name + "Union"; - } - default: { - return field.IsScalarOptional() ? GenOptionalDecl(type) - : GenTypeBasic(type, true); - } - } - } - - // Return a C++ type for any type (scalar/pointer) specifically for - // using a flatbuffer. - std::string GenTypeGet(const Type &type, const char *afterbasic, - const char *beforeptr, const char *afterptr, - bool user_facing_type) { - if (IsScalar(type.base_type)) { - return GenTypeBasic(type, user_facing_type) + afterbasic; - } else if (IsArray(type)) { - auto element_type = type.VectorType(); - // Check if enum arrays are used in C++ without specifying --scoped-enums - if (IsEnum(element_type) && !opts_.g_only_fixed_enums) { - LogCompilerError( - "--scoped-enums must be enabled to use enum arrays in C++"); - FLATBUFFERS_ASSERT(true); - } - return beforeptr + - (IsScalar(element_type.base_type) - ? GenTypeBasic(element_type, user_facing_type) - : GenTypePointer(element_type)) + - afterptr; - } else { - return beforeptr + GenTypePointer(type) + afterptr; - } - } - - std::string GenTypeSpan(const Type &type, bool immutable, size_t extent) { - // Generate "flatbuffers::span<const U, extent>". - FLATBUFFERS_ASSERT(IsSeries(type) && "unexpected type"); - auto element_type = type.VectorType(); - std::string text = "flatbuffers::span<"; - text += immutable ? "const " : ""; - if (IsScalar(element_type.base_type)) { - text += GenTypeBasic(element_type, IsEnum(element_type)); - } else { - switch (element_type.base_type) { - case BASE_TYPE_STRING: { - text += "char"; - break; - } - case BASE_TYPE_STRUCT: { - FLATBUFFERS_ASSERT(type.struct_def); - text += WrapInNameSpace(*type.struct_def); - break; - } - default: - FLATBUFFERS_ASSERT(false && "unexpected element's type"); - break; - } - } - if (extent != flatbuffers::dynamic_extent) { - text += ", "; - text += NumToString(extent); - } - text += "> "; - return text; - } - - std::string GenEnumValDecl(const EnumDef &enum_def, - const std::string &enum_val) const { - return opts_.prefixed_enums ? Name(enum_def) + "_" + enum_val : enum_val; - } - - std::string GetEnumValUse(const EnumDef &enum_def, - const EnumVal &enum_val) const { - if (opts_.scoped_enums) { - return Name(enum_def) + "::" + Name(enum_val); - } else if (opts_.prefixed_enums) { - return Name(enum_def) + "_" + Name(enum_val); - } else { - return Name(enum_val); - } - } - - std::string StripUnionType(const std::string &name) { - return name.substr(0, name.size() - strlen(UnionTypeFieldSuffix())); - } - - std::string GetUnionElement(const EnumVal &ev, bool native_type, - const IDLOptions &opts) { - if (ev.union_type.base_type == BASE_TYPE_STRUCT) { - auto name = ev.union_type.struct_def->name; - if (native_type) { - name = NativeName(name, ev.union_type.struct_def, opts); - } - return WrapInNameSpace(ev.union_type.struct_def->defined_namespace, name); - } else if (IsString(ev.union_type)) { - return native_type ? "std::string" : "flatbuffers::String"; - } else { - FLATBUFFERS_ASSERT(false); - return Name(ev); - } - } - - std::string UnionVerifySignature(const EnumDef &enum_def) { - return "bool Verify" + Name(enum_def) + - "(flatbuffers::Verifier &verifier, const void *obj, " + - Name(enum_def) + " type)"; - } - - std::string UnionVectorVerifySignature(const EnumDef &enum_def) { - return "bool Verify" + Name(enum_def) + "Vector" + - "(flatbuffers::Verifier &verifier, " + - "const flatbuffers::Vector<flatbuffers::Offset<void>> *values, " + - "const flatbuffers::Vector<uint8_t> *types)"; - } - - std::string UnionUnPackSignature(const EnumDef &enum_def, bool inclass) { - return (inclass ? "static " : "") + std::string("void *") + - (inclass ? "" : Name(enum_def) + "Union::") + - "UnPack(const void *obj, " + Name(enum_def) + - " type, const flatbuffers::resolver_function_t *resolver)"; - } - - std::string UnionPackSignature(const EnumDef &enum_def, bool inclass) { - return "flatbuffers::Offset<void> " + - (inclass ? "" : Name(enum_def) + "Union::") + - "Pack(flatbuffers::FlatBufferBuilder &_fbb, " + - "const flatbuffers::rehasher_function_t *_rehasher" + - (inclass ? " = nullptr" : "") + ") const"; - } - - std::string TableCreateSignature(const StructDef &struct_def, bool predecl, - const IDLOptions &opts) { - return "flatbuffers::Offset<" + Name(struct_def) + "> Create" + - Name(struct_def) + "(flatbuffers::FlatBufferBuilder &_fbb, const " + - NativeName(Name(struct_def), &struct_def, opts) + - " *_o, const flatbuffers::rehasher_function_t *_rehasher" + - (predecl ? " = nullptr" : "") + ")"; - } - - std::string TablePackSignature(const StructDef &struct_def, bool inclass, - const IDLOptions &opts) { - return std::string(inclass ? "static " : "") + "flatbuffers::Offset<" + - Name(struct_def) + "> " + (inclass ? "" : Name(struct_def) + "::") + - "Pack(flatbuffers::FlatBufferBuilder &_fbb, " + "const " + - NativeName(Name(struct_def), &struct_def, opts) + "* _o, " + - "const flatbuffers::rehasher_function_t *_rehasher" + - (inclass ? " = nullptr" : "") + ")"; - } - - std::string TableUnPackSignature(const StructDef &struct_def, bool inclass, - const IDLOptions &opts) { - return NativeName(Name(struct_def), &struct_def, opts) + " *" + - (inclass ? "" : Name(struct_def) + "::") + - "UnPack(const flatbuffers::resolver_function_t *_resolver" + - (inclass ? " = nullptr" : "") + ") const"; - } - - std::string TableUnPackToSignature(const StructDef &struct_def, bool inclass, - const IDLOptions &opts) { - return "void " + (inclass ? "" : Name(struct_def) + "::") + "UnPackTo(" + - NativeName(Name(struct_def), &struct_def, opts) + " *" + - "_o, const flatbuffers::resolver_function_t *_resolver" + - (inclass ? " = nullptr" : "") + ") const"; - } - - void GenMiniReflectPre(const StructDef *struct_def) { - code_.SetValue("NAME", struct_def->name); - code_ += "inline const flatbuffers::TypeTable *{{NAME}}TypeTable();"; - code_ += ""; - } - - void GenMiniReflect(const StructDef *struct_def, const EnumDef *enum_def) { - code_.SetValue("NAME", struct_def ? struct_def->name : enum_def->name); - code_.SetValue("SEQ_TYPE", - struct_def ? (struct_def->fixed ? "ST_STRUCT" : "ST_TABLE") - : (enum_def->is_union ? "ST_UNION" : "ST_ENUM")); - auto num_fields = - struct_def ? struct_def->fields.vec.size() : enum_def->size(); - code_.SetValue("NUM_FIELDS", NumToString(num_fields)); - std::vector<std::string> names; - std::vector<Type> types; - - if (struct_def) { - for (auto it = struct_def->fields.vec.begin(); - it != struct_def->fields.vec.end(); ++it) { - const auto &field = **it; - names.push_back(Name(field)); - types.push_back(field.value.type); - } - } else { - for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end(); - ++it) { - const auto &ev = **it; - names.push_back(Name(ev)); - types.push_back(enum_def->is_union ? ev.union_type - : Type(enum_def->underlying_type)); - } - } - std::string ts; - std::vector<std::string> type_refs; - std::vector<uint16_t> array_sizes; - for (auto it = types.begin(); it != types.end(); ++it) { - auto &type = *it; - if (!ts.empty()) ts += ",\n "; - auto is_vector = IsVector(type); - auto is_array = IsArray(type); - auto bt = is_vector || is_array ? type.element : type.base_type; - auto et = IsScalar(bt) || bt == BASE_TYPE_STRING - ? bt - BASE_TYPE_UTYPE + ET_UTYPE - : ET_SEQUENCE; - int ref_idx = -1; - std::string ref_name = - type.struct_def - ? WrapInNameSpace(*type.struct_def) - : type.enum_def ? WrapInNameSpace(*type.enum_def) : ""; - if (!ref_name.empty()) { - auto rit = type_refs.begin(); - for (; rit != type_refs.end(); ++rit) { - if (*rit == ref_name) { - ref_idx = static_cast<int>(rit - type_refs.begin()); - break; - } - } - if (rit == type_refs.end()) { - ref_idx = static_cast<int>(type_refs.size()); - type_refs.push_back(ref_name); - } - } - if (is_array) { array_sizes.push_back(type.fixed_length); } - ts += "{ flatbuffers::" + std::string(ElementaryTypeNames()[et]) + ", " + - NumToString(is_vector || is_array) + ", " + NumToString(ref_idx) + - " }"; - } - std::string rs; - for (auto it = type_refs.begin(); it != type_refs.end(); ++it) { - if (!rs.empty()) rs += ",\n "; - rs += *it + "TypeTable"; - } - std::string as; - for (auto it = array_sizes.begin(); it != array_sizes.end(); ++it) { - as += NumToString(*it); - as += ", "; - } - std::string ns; - for (auto it = names.begin(); it != names.end(); ++it) { - if (!ns.empty()) ns += ",\n "; - ns += "\"" + *it + "\""; - } - std::string vs; - const auto consecutive_enum_from_zero = - enum_def && enum_def->MinValue()->IsZero() && - ((enum_def->size() - 1) == enum_def->Distance()); - if (enum_def && !consecutive_enum_from_zero) { - for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end(); - ++it) { - const auto &ev = **it; - if (!vs.empty()) vs += ", "; - vs += NumToStringCpp(enum_def->ToString(ev), - enum_def->underlying_type.base_type); - } - } else if (struct_def && struct_def->fixed) { - for (auto it = struct_def->fields.vec.begin(); - it != struct_def->fields.vec.end(); ++it) { - const auto &field = **it; - vs += NumToString(field.value.offset); - vs += ", "; - } - vs += NumToString(struct_def->bytesize); - } - code_.SetValue("TYPES", ts); - code_.SetValue("REFS", rs); - code_.SetValue("ARRAYSIZES", as); - code_.SetValue("NAMES", ns); - code_.SetValue("VALUES", vs); - code_ += "inline const flatbuffers::TypeTable *{{NAME}}TypeTable() {"; - if (num_fields) { - code_ += " static const flatbuffers::TypeCode type_codes[] = {"; - code_ += " {{TYPES}}"; - code_ += " };"; - } - if (!type_refs.empty()) { - code_ += " static const flatbuffers::TypeFunction type_refs[] = {"; - code_ += " {{REFS}}"; - code_ += " };"; - } - if (!as.empty()) { - code_ += " static const int16_t array_sizes[] = { {{ARRAYSIZES}} };"; - } - if (!vs.empty()) { - // Problem with uint64_t values greater than 9223372036854775807ULL. - code_ += " static const int64_t values[] = { {{VALUES}} };"; - } - auto has_names = - num_fields && opts_.mini_reflect == IDLOptions::kTypesAndNames; - if (has_names) { - code_ += " static const char * const names[] = {"; - code_ += " {{NAMES}}"; - code_ += " };"; - } - code_ += " static const flatbuffers::TypeTable tt = {"; - code_ += std::string(" flatbuffers::{{SEQ_TYPE}}, {{NUM_FIELDS}}, ") + - (num_fields ? "type_codes, " : "nullptr, ") + - (!type_refs.empty() ? "type_refs, " : "nullptr, ") + - (!as.empty() ? "array_sizes, " : "nullptr, ") + - (!vs.empty() ? "values, " : "nullptr, ") + - (has_names ? "names" : "nullptr"); - code_ += " };"; - code_ += " return &tt;"; - code_ += "}"; - code_ += ""; - } - - // Generate an enum declaration, - // an enum string lookup table, - // and an enum array of values - - void GenEnum(const EnumDef &enum_def) { - code_.SetValue("ENUM_NAME", Name(enum_def)); - code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false)); - - GenComment(enum_def.doc_comment); - code_ += - (opts_.scoped_enums ? "enum class " : "enum ") + Name(enum_def) + "\\"; - if (opts_.g_only_fixed_enums) { code_ += " : {{BASE_TYPE}}\\"; } - code_ += " {"; - - code_.SetValue("SEP", ","); - auto add_sep = false; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - const auto &ev = **it; - if (add_sep) code_ += "{{SEP}}"; - GenComment(ev.doc_comment, " "); - code_.SetValue("KEY", GenEnumValDecl(enum_def, Name(ev))); - code_.SetValue("VALUE", - NumToStringCpp(enum_def.ToString(ev), - enum_def.underlying_type.base_type)); - code_ += " {{KEY}} = {{VALUE}}\\"; - add_sep = true; - } - const EnumVal *minv = enum_def.MinValue(); - const EnumVal *maxv = enum_def.MaxValue(); - - if (opts_.scoped_enums || opts_.prefixed_enums) { - FLATBUFFERS_ASSERT(minv && maxv); - - code_.SetValue("SEP", ",\n"); - if (enum_def.attributes.Lookup("bit_flags")) { - code_.SetValue("KEY", GenEnumValDecl(enum_def, "NONE")); - code_.SetValue("VALUE", "0"); - code_ += "{{SEP}} {{KEY}} = {{VALUE}}\\"; - - code_.SetValue("KEY", GenEnumValDecl(enum_def, "ANY")); - code_.SetValue("VALUE", - NumToStringCpp(enum_def.AllFlags(), - enum_def.underlying_type.base_type)); - code_ += "{{SEP}} {{KEY}} = {{VALUE}}\\"; - } else { // MIN & MAX are useless for bit_flags - code_.SetValue("KEY", GenEnumValDecl(enum_def, "MIN")); - code_.SetValue("VALUE", GenEnumValDecl(enum_def, Name(*minv))); - code_ += "{{SEP}} {{KEY}} = {{VALUE}}\\"; - - code_.SetValue("KEY", GenEnumValDecl(enum_def, "MAX")); - code_.SetValue("VALUE", GenEnumValDecl(enum_def, Name(*maxv))); - code_ += "{{SEP}} {{KEY}} = {{VALUE}}\\"; - } - } - code_ += ""; - code_ += "};"; - - if (opts_.scoped_enums && enum_def.attributes.Lookup("bit_flags")) { - code_ += - "FLATBUFFERS_DEFINE_BITMASK_OPERATORS({{ENUM_NAME}}, {{BASE_TYPE}})"; - } - code_ += ""; - - // Generate an array of all enumeration values - auto num_fields = NumToString(enum_def.size()); - code_ += "inline const {{ENUM_NAME}} (&EnumValues{{ENUM_NAME}}())[" + - num_fields + "] {"; - code_ += " static const {{ENUM_NAME}} values[] = {"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - const auto &ev = **it; - auto value = GetEnumValUse(enum_def, ev); - auto suffix = *it != enum_def.Vals().back() ? "," : ""; - code_ += " " + value + suffix; - } - code_ += " };"; - code_ += " return values;"; - code_ += "}"; - code_ += ""; - - // Generate a generate string table for enum values. - // Problem is, if values are very sparse that could generate really big - // tables. Ideally in that case we generate a map lookup instead, but for - // the moment we simply don't output a table at all. - auto range = enum_def.Distance(); - // Average distance between values above which we consider a table - // "too sparse". Change at will. - static const uint64_t kMaxSparseness = 5; - if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) { - code_ += "inline const char * const *EnumNames{{ENUM_NAME}}() {"; - code_ += " static const char * const names[" + - NumToString(range + 1 + 1) + "] = {"; - - auto val = enum_def.Vals().front(); - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - auto ev = *it; - for (auto k = enum_def.Distance(val, ev); k > 1; --k) { - code_ += " \"\","; - } - val = ev; - code_ += " \"" + Name(*ev) + "\","; - } - code_ += " nullptr"; - code_ += " };"; - - code_ += " return names;"; - code_ += "}"; - code_ += ""; - - code_ += "inline const char *EnumName{{ENUM_NAME}}({{ENUM_NAME}} e) {"; - - code_ += " if (flatbuffers::IsOutRange(e, " + - GetEnumValUse(enum_def, *enum_def.MinValue()) + ", " + - GetEnumValUse(enum_def, *enum_def.MaxValue()) + - ")) return \"\";"; - - code_ += " const size_t index = static_cast<size_t>(e)\\"; - if (enum_def.MinValue()->IsNonZero()) { - auto vals = GetEnumValUse(enum_def, *enum_def.MinValue()); - code_ += " - static_cast<size_t>(" + vals + ")\\"; - } - code_ += ";"; - - code_ += " return EnumNames{{ENUM_NAME}}()[index];"; - code_ += "}"; - code_ += ""; - } else { - code_ += "inline const char *EnumName{{ENUM_NAME}}({{ENUM_NAME}} e) {"; - - code_ += " switch (e) {"; - - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - const auto &ev = **it; - code_ += " case " + GetEnumValUse(enum_def, ev) + ": return \"" + - Name(ev) + "\";"; - } - - code_ += " default: return \"\";"; - code_ += " }"; - - code_ += "}"; - code_ += ""; - } - - // Generate type traits for unions to map from a type to union enum value. - if (enum_def.is_union && !enum_def.uses_multiple_type_instances) { - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - const auto &ev = **it; - - if (it == enum_def.Vals().begin()) { - code_ += "template<typename T> struct {{ENUM_NAME}}Traits {"; - } else { - auto name = GetUnionElement(ev, false, opts_); - code_ += "template<> struct {{ENUM_NAME}}Traits<" + name + "> {"; - } - - auto value = GetEnumValUse(enum_def, ev); - code_ += " static const {{ENUM_NAME}} enum_value = " + value + ";"; - code_ += "};"; - code_ += ""; - } - } - - if (opts_.generate_object_based_api && enum_def.is_union) { - // Generate a union type - code_.SetValue("NAME", Name(enum_def)); - FLATBUFFERS_ASSERT(enum_def.Lookup("NONE")); - code_.SetValue("NONE", GetEnumValUse(enum_def, *enum_def.Lookup("NONE"))); - - code_ += "struct {{NAME}}Union {"; - code_ += " {{NAME}} type;"; - code_ += " void *value;"; - code_ += ""; - code_ += " {{NAME}}Union() : type({{NONE}}), value(nullptr) {}"; - code_ += " {{NAME}}Union({{NAME}}Union&& u) FLATBUFFERS_NOEXCEPT :"; - code_ += " type({{NONE}}), value(nullptr)"; - code_ += " { std::swap(type, u.type); std::swap(value, u.value); }"; - code_ += " {{NAME}}Union(const {{NAME}}Union &);"; - code_ += " {{NAME}}Union &operator=(const {{NAME}}Union &u)"; - code_ += - " { {{NAME}}Union t(u); std::swap(type, t.type); std::swap(value, " - "t.value); return *this; }"; - code_ += - " {{NAME}}Union &operator=({{NAME}}Union &&u) FLATBUFFERS_NOEXCEPT"; - code_ += - " { std::swap(type, u.type); std::swap(value, u.value); return " - "*this; }"; - code_ += " ~{{NAME}}Union() { Reset(); }"; - code_ += ""; - code_ += " void Reset();"; - code_ += ""; - if (!enum_def.uses_multiple_type_instances) { - code_ += "#ifndef FLATBUFFERS_CPP98_STL"; - code_ += " template <typename T>"; - code_ += " void Set(T&& val) {"; - code_ += " using RT = typename std::remove_reference<T>::type;"; - code_ += " Reset();"; - code_ += - " type = {{NAME}}Traits<typename RT::TableType>::enum_value;"; - code_ += " if (type != {{NONE}}) {"; - code_ += " value = new RT(std::forward<T>(val));"; - code_ += " }"; - code_ += " }"; - code_ += "#endif // FLATBUFFERS_CPP98_STL"; - code_ += ""; - } - code_ += " " + UnionUnPackSignature(enum_def, true) + ";"; - code_ += " " + UnionPackSignature(enum_def, true) + ";"; - code_ += ""; - - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - const auto &ev = **it; - if (ev.IsZero()) { continue; } - - const auto native_type = GetUnionElement(ev, true, opts_); - code_.SetValue("NATIVE_TYPE", native_type); - code_.SetValue("NATIVE_NAME", Name(ev)); - code_.SetValue("NATIVE_ID", GetEnumValUse(enum_def, ev)); - - code_ += " {{NATIVE_TYPE}} *As{{NATIVE_NAME}}() {"; - code_ += " return type == {{NATIVE_ID}} ?"; - code_ += " reinterpret_cast<{{NATIVE_TYPE}} *>(value) : nullptr;"; - code_ += " }"; - - code_ += " const {{NATIVE_TYPE}} *As{{NATIVE_NAME}}() const {"; - code_ += " return type == {{NATIVE_ID}} ?"; - code_ += - " reinterpret_cast<const {{NATIVE_TYPE}} *>(value) : nullptr;"; - code_ += " }"; - } - code_ += "};"; - code_ += ""; - - if (opts_.gen_compare) { - code_ += ""; - code_ += - "inline bool operator==(const {{NAME}}Union &lhs, const " - "{{NAME}}Union &rhs) {"; - code_ += " if (lhs.type != rhs.type) return false;"; - code_ += " switch (lhs.type) {"; - - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - const auto &ev = **it; - code_.SetValue("NATIVE_ID", GetEnumValUse(enum_def, ev)); - if (ev.IsNonZero()) { - const auto native_type = GetUnionElement(ev, true, opts_); - code_.SetValue("NATIVE_TYPE", native_type); - code_ += " case {{NATIVE_ID}}: {"; - code_ += - " return *(reinterpret_cast<const {{NATIVE_TYPE}} " - "*>(lhs.value)) =="; - code_ += - " *(reinterpret_cast<const {{NATIVE_TYPE}} " - "*>(rhs.value));"; - code_ += " }"; - } else { - code_ += " case {{NATIVE_ID}}: {"; - code_ += " return true;"; // "NONE" enum value. - code_ += " }"; - } - } - code_ += " default: {"; - code_ += " return false;"; - code_ += " }"; - code_ += " }"; - code_ += "}"; - - code_ += ""; - code_ += - "inline bool operator!=(const {{NAME}}Union &lhs, const " - "{{NAME}}Union &rhs) {"; - code_ += " return !(lhs == rhs);"; - code_ += "}"; - code_ += ""; - } - } - - if (enum_def.is_union) { - code_ += UnionVerifySignature(enum_def) + ";"; - code_ += UnionVectorVerifySignature(enum_def) + ";"; - code_ += ""; - } - } - - void GenUnionPost(const EnumDef &enum_def) { - // Generate a verifier function for this union that can be called by the - // table verifier functions. It uses a switch case to select a specific - // verifier function to call, this should be safe even if the union type - // has been corrupted, since the verifiers will simply fail when called - // on the wrong type. - code_.SetValue("ENUM_NAME", Name(enum_def)); - - code_ += "inline " + UnionVerifySignature(enum_def) + " {"; - code_ += " switch (type) {"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - const auto &ev = **it; - code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); - - if (ev.IsNonZero()) { - code_.SetValue("TYPE", GetUnionElement(ev, false, opts_)); - code_ += " case {{LABEL}}: {"; - auto getptr = - " auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);"; - if (ev.union_type.base_type == BASE_TYPE_STRUCT) { - if (ev.union_type.struct_def->fixed) { - code_ += - " return verifier.Verify<{{TYPE}}>(static_cast<const " - "uint8_t *>(obj), 0);"; - } else { - code_ += getptr; - code_ += " return verifier.VerifyTable(ptr);"; - } - } else if (IsString(ev.union_type)) { - code_ += getptr; - code_ += " return verifier.VerifyString(ptr);"; - } else { - FLATBUFFERS_ASSERT(false); - } - code_ += " }"; - } else { - code_ += " case {{LABEL}}: {"; - code_ += " return true;"; // "NONE" enum value. - code_ += " }"; - } - } - code_ += " default: return true;"; // unknown values are OK. - code_ += " }"; - code_ += "}"; - code_ += ""; - - code_ += "inline " + UnionVectorVerifySignature(enum_def) + " {"; - code_ += " if (!values || !types) return !values && !types;"; - code_ += " if (values->size() != types->size()) return false;"; - code_ += " for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {"; - code_ += " if (!Verify" + Name(enum_def) + "("; - code_ += " verifier, values->Get(i), types->GetEnum<" + - Name(enum_def) + ">(i))) {"; - code_ += " return false;"; - code_ += " }"; - code_ += " }"; - code_ += " return true;"; - code_ += "}"; - code_ += ""; - - if (opts_.generate_object_based_api) { - // Generate union Unpack() and Pack() functions. - code_ += "inline " + UnionUnPackSignature(enum_def, false) + " {"; - code_ += " switch (type) {"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - const auto &ev = **it; - if (ev.IsZero()) { continue; } - - code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); - code_.SetValue("TYPE", GetUnionElement(ev, false, opts_)); - code_ += " case {{LABEL}}: {"; - code_ += " auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);"; - if (ev.union_type.base_type == BASE_TYPE_STRUCT) { - if (ev.union_type.struct_def->fixed) { - code_ += " return new " + - WrapInNameSpace(*ev.union_type.struct_def) + "(*ptr);"; - } else { - code_ += " return ptr->UnPack(resolver);"; - } - } else if (IsString(ev.union_type)) { - code_ += " return new std::string(ptr->c_str(), ptr->size());"; - } else { - FLATBUFFERS_ASSERT(false); - } - code_ += " }"; - } - code_ += " default: return nullptr;"; - code_ += " }"; - code_ += "}"; - code_ += ""; - - code_ += "inline " + UnionPackSignature(enum_def, false) + " {"; - code_ += " switch (type) {"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - auto &ev = **it; - if (ev.IsZero()) { continue; } - - code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); - code_.SetValue("TYPE", GetUnionElement(ev, true, opts_)); - code_ += " case {{LABEL}}: {"; - code_ += " auto ptr = reinterpret_cast<const {{TYPE}} *>(value);"; - if (ev.union_type.base_type == BASE_TYPE_STRUCT) { - if (ev.union_type.struct_def->fixed) { - code_ += " return _fbb.CreateStruct(*ptr).Union();"; - } else { - code_.SetValue("NAME", ev.union_type.struct_def->name); - code_ += - " return Create{{NAME}}(_fbb, ptr, _rehasher).Union();"; - } - } else if (IsString(ev.union_type)) { - code_ += " return _fbb.CreateString(*ptr).Union();"; - } else { - FLATBUFFERS_ASSERT(false); - } - code_ += " }"; - } - code_ += " default: return 0;"; - code_ += " }"; - code_ += "}"; - code_ += ""; - - // Union copy constructor - code_ += - "inline {{ENUM_NAME}}Union::{{ENUM_NAME}}Union(const " - "{{ENUM_NAME}}Union &u) : type(u.type), value(nullptr) {"; - code_ += " switch (type) {"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - const auto &ev = **it; - if (ev.IsZero()) { continue; } - code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); - code_.SetValue("TYPE", GetUnionElement(ev, true, opts_)); - code_ += " case {{LABEL}}: {"; - bool copyable = true; - if (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. - for (auto fit = ev.union_type.struct_def->fields.vec.begin(); - fit != ev.union_type.struct_def->fields.vec.end(); ++fit) { - const auto &field = **fit; - if (!field.deprecated && field.value.type.struct_def && - !field.native_inline) { - copyable = false; - break; - } - } - } - if (copyable) { - code_ += - " value = new {{TYPE}}(*reinterpret_cast<{{TYPE}} *>" - "(u.value));"; - } else { - code_ += - " FLATBUFFERS_ASSERT(false); // {{TYPE}} not copyable."; - } - code_ += " break;"; - code_ += " }"; - } - code_ += " default:"; - code_ += " break;"; - code_ += " }"; - code_ += "}"; - code_ += ""; - - // Union Reset() function. - FLATBUFFERS_ASSERT(enum_def.Lookup("NONE")); - code_.SetValue("NONE", GetEnumValUse(enum_def, *enum_def.Lookup("NONE"))); - - code_ += "inline void {{ENUM_NAME}}Union::Reset() {"; - code_ += " switch (type) {"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - const auto &ev = **it; - if (ev.IsZero()) { continue; } - code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); - code_.SetValue("TYPE", GetUnionElement(ev, true, opts_)); - code_ += " case {{LABEL}}: {"; - code_ += " auto ptr = reinterpret_cast<{{TYPE}} *>(value);"; - code_ += " delete ptr;"; - code_ += " break;"; - code_ += " }"; - } - code_ += " default: break;"; - code_ += " }"; - code_ += " value = nullptr;"; - code_ += " type = {{NONE}};"; - code_ += "}"; - code_ += ""; - } - } - - // Generates a value with optionally a cast applied if the field has a - // different underlying type from its interface type (currently only the - // case for enums. "from" specify the direction, true meaning from the - // underlying type to the interface type. - std::string GenUnderlyingCast(const FieldDef &field, bool from, - const std::string &val) { - if (from && field.value.type.base_type == BASE_TYPE_BOOL) { - return val + " != 0"; - } else if ((field.value.type.enum_def && - IsScalar(field.value.type.base_type)) || - field.value.type.base_type == BASE_TYPE_BOOL) { - return "static_cast<" + GenTypeBasic(field.value.type, from) + ">(" + - val + ")"; - } else { - return val; - } - } - - std::string GenFieldOffsetName(const FieldDef &field) { - std::string uname = Name(field); - std::transform(uname.begin(), uname.end(), uname.begin(), CharToUpper); - return "VT_" + uname; - } - - void GenFullyQualifiedNameGetter(const StructDef &struct_def, - const std::string &name) { - if (!opts_.generate_name_strings) { return; } - auto fullname = struct_def.defined_namespace->GetFullyQualifiedName(name); - code_.SetValue("NAME", fullname); - code_.SetValue("CONSTEXPR", "FLATBUFFERS_CONSTEXPR"); - code_ += " static {{CONSTEXPR}} const char *GetFullyQualifiedName() {"; - code_ += " return \"{{NAME}}\";"; - code_ += " }"; - } - - std::string GenDefaultConstant(const FieldDef &field) { - if (IsFloat(field.value.type.base_type)) - return float_const_gen_.GenFloatConstant(field); - else - return NumToStringCpp(field.value.constant, field.value.type.base_type); - } - - std::string GetDefaultScalarValue(const FieldDef &field, bool is_ctor) { - const auto &type = field.value.type; - if (field.IsScalarOptional()) { - return GenOptionalNull(); - } else if (type.enum_def && IsScalar(type.base_type)) { - auto ev = type.enum_def->FindByValue(field.value.constant); - if (ev) { - return WrapInNameSpace(type.enum_def->defined_namespace, - GetEnumValUse(*type.enum_def, *ev)); - } else { - return GenUnderlyingCast( - field, true, NumToStringCpp(field.value.constant, type.base_type)); - } - } else if (type.base_type == BASE_TYPE_BOOL) { - return field.value.constant == "0" ? "false" : "true"; - } else if (field.attributes.Lookup("cpp_type")) { - if (is_ctor) { - if (PtrType(&field) == "naked") { - return "nullptr"; - } else { - return ""; - } - } else { - return "0"; - } - } else { - return GenDefaultConstant(field); - } - } - - void GenParam(const FieldDef &field, bool direct, const char *prefix) { - code_.SetValue("PRE", prefix); - code_.SetValue("PARAM_NAME", Name(field)); - if (direct && IsString(field.value.type)) { - code_.SetValue("PARAM_TYPE", "const char *"); - code_.SetValue("PARAM_VALUE", "nullptr"); - } else if (direct && IsVector(field.value.type)) { - const auto vtype = field.value.type.VectorType(); - std::string type; - if (IsStruct(vtype)) { - type = WrapInNameSpace(*vtype.struct_def); - } else { - type = GenTypeWire(vtype, "", VectorElementUserFacing(vtype)); - } - if (TypeHasKey(vtype)) { - code_.SetValue("PARAM_TYPE", "std::vector<" + type + "> *"); - } else { - code_.SetValue("PARAM_TYPE", "const std::vector<" + type + "> *"); - } - code_.SetValue("PARAM_VALUE", "nullptr"); - } else { - const auto &type = field.value.type; - code_.SetValue("PARAM_VALUE", GetDefaultScalarValue(field, false)); - if (field.IsScalarOptional()) - code_.SetValue("PARAM_TYPE", GenOptionalDecl(type) + " "); - else - code_.SetValue("PARAM_TYPE", GenTypeWire(type, " ", true)); - } - code_ += "{{PRE}}{{PARAM_TYPE}}{{PARAM_NAME}} = {{PARAM_VALUE}}\\"; - } - - // Generate a member, including a default value for scalars and raw pointers. - void GenMember(const FieldDef &field) { - if (!field.deprecated && // Deprecated fields won't be accessible. - field.value.type.base_type != BASE_TYPE_UTYPE && - (field.value.type.base_type != BASE_TYPE_VECTOR || - field.value.type.element != BASE_TYPE_UTYPE)) { - auto type = GenTypeNative(field.value.type, false, field); - auto cpp_type = field.attributes.Lookup("cpp_type"); - auto full_type = - (cpp_type - ? (IsVector(field.value.type) - ? "std::vector<" + - GenTypeNativePtr(cpp_type->constant, &field, - false) + - "> " - : GenTypeNativePtr(cpp_type->constant, &field, false)) - : type + " "); - // Generate default member initializers for >= C++11. - std::string field_di = ""; - if (opts_.g_cpp_std >= cpp::CPP_STD_11) { - field_di = "{}"; - auto native_default = field.attributes.Lookup("native_default"); - // Scalar types get parsed defaults, raw pointers get nullptrs. - if (IsScalar(field.value.type.base_type)) { - field_di = - " = " + (native_default ? std::string(native_default->constant) - : GetDefaultScalarValue(field, true)); - } else if (field.value.type.base_type == BASE_TYPE_STRUCT) { - if (IsStruct(field.value.type) && native_default) { - field_di = " = " + native_default->constant; - } - } - } - code_.SetValue("FIELD_TYPE", full_type); - code_.SetValue("FIELD_NAME", Name(field)); - code_.SetValue("FIELD_DI", field_di); - code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}{{FIELD_DI}};"; - } - } - - // 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; } - std::string initializer_list; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (!field.deprecated && // Deprecated fields won't be accessible. - field.value.type.base_type != BASE_TYPE_UTYPE) { - auto cpp_type = field.attributes.Lookup("cpp_type"); - auto native_default = field.attributes.Lookup("native_default"); - // Scalar types get parsed defaults, raw pointers get nullptrs. - if (IsScalar(field.value.type.base_type)) { - if (!initializer_list.empty()) { initializer_list += ",\n "; } - initializer_list += Name(field); - initializer_list += - "(" + - (native_default ? std::string(native_default->constant) - : GetDefaultScalarValue(field, true)) + - ")"; - } else if (field.value.type.base_type == BASE_TYPE_STRUCT) { - if (IsStruct(field.value.type)) { - if (native_default) { - if (!initializer_list.empty()) { - initializer_list += ",\n "; - } - initializer_list += - Name(field) + "(" + native_default->constant + ")"; - } - } - } else if (cpp_type && field.value.type.base_type != BASE_TYPE_VECTOR) { - if (!initializer_list.empty()) { initializer_list += ",\n "; } - initializer_list += Name(field) + "(0)"; - } - } - } - if (!initializer_list.empty()) { - initializer_list = "\n : " + initializer_list; - } - - code_.SetValue("INIT_LIST", initializer_list); - - code_ += " {{NATIVE_NAME}}(){{INIT_LIST}} {"; - code_ += " }"; - } - - void GenCompareOperator(const StructDef &struct_def, - std::string accessSuffix = "") { - std::string compare_op; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (!field.deprecated && // Deprecated fields won't be accessible. - field.value.type.base_type != BASE_TYPE_UTYPE && - (field.value.type.base_type != BASE_TYPE_VECTOR || - field.value.type.element != BASE_TYPE_UTYPE)) { - if (!compare_op.empty()) { compare_op += " &&\n "; } - auto accessor = Name(field) + accessSuffix; - compare_op += "(lhs." + accessor + " == rhs." + accessor + ")"; - } - } - - std::string cmp_lhs; - std::string cmp_rhs; - if (compare_op.empty()) { - cmp_lhs = ""; - cmp_rhs = ""; - compare_op = " return true;"; - } else { - cmp_lhs = "lhs"; - cmp_rhs = "rhs"; - compare_op = " return\n " + compare_op + ";"; - } - - code_.SetValue("CMP_OP", compare_op); - code_.SetValue("CMP_LHS", cmp_lhs); - code_.SetValue("CMP_RHS", cmp_rhs); - code_ += ""; - code_ += - "inline bool operator==(const {{NATIVE_NAME}} &{{CMP_LHS}}, const " - "{{NATIVE_NAME}} &{{CMP_RHS}}) {"; - code_ += "{{CMP_OP}}"; - code_ += "}"; - - code_ += ""; - code_ += - "inline bool operator!=(const {{NATIVE_NAME}} &lhs, const " - "{{NATIVE_NAME}} &rhs) {"; - code_ += " return !(lhs == rhs);"; - code_ += "}"; - code_ += ""; - } - - void GenOperatorNewDelete(const StructDef &struct_def) { - if (auto native_custom_alloc = - struct_def.attributes.Lookup("native_custom_alloc")) { - code_ += " inline void *operator new (std::size_t count) {"; - code_ += " return " + native_custom_alloc->constant + - "<{{NATIVE_NAME}}>().allocate(count / sizeof({{NATIVE_NAME}}));"; - code_ += " }"; - code_ += " inline void operator delete (void *ptr) {"; - code_ += " return " + native_custom_alloc->constant + - "<{{NATIVE_NAME}}>().deallocate(static_cast<{{NATIVE_NAME}}*>(" - "ptr),1);"; - code_ += " }"; - } - } - - void GenNativeTable(const StructDef &struct_def) { - const auto native_name = NativeName(Name(struct_def), &struct_def, opts_); - code_.SetValue("STRUCT_NAME", Name(struct_def)); - code_.SetValue("NATIVE_NAME", native_name); - - // Generate a C++ object that can hold an unpacked version of this table. - code_ += "struct {{NATIVE_NAME}} : public flatbuffers::NativeTable {"; - code_ += " typedef {{STRUCT_NAME}} TableType;"; - GenFullyQualifiedNameGetter(struct_def, native_name); - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - GenMember(**it); - } - GenOperatorNewDelete(struct_def); - GenDefaultConstructor(struct_def); - code_ += "};"; - if (opts_.gen_compare) GenCompareOperator(struct_def); - code_ += ""; - } - - // Generate the code to call the appropriate Verify function(s) for a field. - void GenVerifyCall(const FieldDef &field, const char *prefix) { - code_.SetValue("PRE", prefix); - code_.SetValue("NAME", Name(field)); - code_.SetValue("REQUIRED", field.IsRequired() ? "Required" : ""); - code_.SetValue("SIZE", GenTypeSize(field.value.type)); - code_.SetValue("OFFSET", GenFieldOffsetName(field)); - if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type)) { - code_ += - "{{PRE}}VerifyField{{REQUIRED}}<{{SIZE}}>(verifier, {{OFFSET}})\\"; - } else { - code_ += "{{PRE}}VerifyOffset{{REQUIRED}}(verifier, {{OFFSET}})\\"; - } - - switch (field.value.type.base_type) { - case BASE_TYPE_UNION: { - code_.SetValue("ENUM_NAME", field.value.type.enum_def->name); - code_.SetValue("SUFFIX", UnionTypeFieldSuffix()); - code_ += - "{{PRE}}Verify{{ENUM_NAME}}(verifier, {{NAME}}(), " - "{{NAME}}{{SUFFIX}}())\\"; - break; - } - case BASE_TYPE_STRUCT: { - if (!field.value.type.struct_def->fixed) { - code_ += "{{PRE}}verifier.VerifyTable({{NAME}}())\\"; - } - break; - } - case BASE_TYPE_STRING: { - code_ += "{{PRE}}verifier.VerifyString({{NAME}}())\\"; - break; - } - case BASE_TYPE_VECTOR: { - code_ += "{{PRE}}verifier.VerifyVector({{NAME}}())\\"; - - switch (field.value.type.element) { - case BASE_TYPE_STRING: { - code_ += "{{PRE}}verifier.VerifyVectorOfStrings({{NAME}}())\\"; - break; - } - case BASE_TYPE_STRUCT: { - if (!field.value.type.struct_def->fixed) { - code_ += "{{PRE}}verifier.VerifyVectorOfTables({{NAME}}())\\"; - } - break; - } - case BASE_TYPE_UNION: { - code_.SetValue("ENUM_NAME", field.value.type.enum_def->name); - code_ += - "{{PRE}}Verify{{ENUM_NAME}}Vector(verifier, {{NAME}}(), " - "{{NAME}}_type())\\"; - break; - } - default: break; - } - break; - } - default: { - break; - } - } - } - - // Generate CompareWithValue method for a key field. - void GenKeyFieldMethods(const FieldDef &field) { - FLATBUFFERS_ASSERT(field.key); - const bool is_string = (IsString(field.value.type)); - - code_ += " bool KeyCompareLessThan(const {{STRUCT_NAME}} *o) const {"; - if (is_string) { - // use operator< of flatbuffers::String - code_ += " return *{{FIELD_NAME}}() < *o->{{FIELD_NAME}}();"; - } else { - code_ += " return {{FIELD_NAME}}() < o->{{FIELD_NAME}}();"; - } - code_ += " }"; - - if (is_string) { - code_ += " int KeyCompareWithValue(const char *val) const {"; - code_ += " return strcmp({{FIELD_NAME}}()->c_str(), val);"; - code_ += " }"; - } else { - FLATBUFFERS_ASSERT(IsScalar(field.value.type.base_type)); - auto type = GenTypeBasic(field.value.type, false); - if (opts_.scoped_enums && field.value.type.enum_def && - IsScalar(field.value.type.base_type)) { - type = GenTypeGet(field.value.type, " ", "const ", " *", true); - } - // Returns {field<val: -1, field==val: 0, field>val: +1}. - code_.SetValue("KEY_TYPE", type); - code_ += " int KeyCompareWithValue({{KEY_TYPE}} val) const {"; - code_ += - " return static_cast<int>({{FIELD_NAME}}() > val) - " - "static_cast<int>({{FIELD_NAME}}() < val);"; - code_ += " }"; - } - } - - void GenTableUnionAsGetters(const FieldDef &field) { - const auto &type = field.value.type; - auto u = type.enum_def; - - if (!type.enum_def->uses_multiple_type_instances) - code_ += - " template<typename T> " - "const T *{{NULLABLE_EXT}}{{FIELD_NAME}}_as() const;"; - - for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) { - auto &ev = **u_it; - if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } - auto full_struct_name = GetUnionElement(ev, false, opts_); - - // @TODO: Mby make this decisions more universal? How? - code_.SetValue("U_GET_TYPE", - EscapeKeyword(field.name + UnionTypeFieldSuffix())); - code_.SetValue("U_ELEMENT_TYPE", WrapInNameSpace(u->defined_namespace, - GetEnumValUse(*u, ev))); - code_.SetValue("U_FIELD_TYPE", "const " + full_struct_name + " *"); - code_.SetValue("U_FIELD_NAME", Name(field) + "_as_" + Name(ev)); - code_.SetValue("U_NULLABLE", NullableExtension()); - - // `const Type *union_name_asType() const` accessor. - code_ += " {{U_FIELD_TYPE}}{{U_NULLABLE}}{{U_FIELD_NAME}}() const {"; - code_ += - " return {{U_GET_TYPE}}() == {{U_ELEMENT_TYPE}} ? " - "static_cast<{{U_FIELD_TYPE}}>({{FIELD_NAME}}()) " - ": nullptr;"; - code_ += " }"; - } - } - - void GenTableFieldGetter(const FieldDef &field) { - const auto &type = field.value.type; - const auto offset_str = GenFieldOffsetName(field); - - GenComment(field.doc_comment, " "); - // Call a different accessor for pointers, that indirects. - if (false == field.IsScalarOptional()) { - const bool is_scalar = IsScalar(type.base_type); - std::string accessor; - if (is_scalar) - accessor = "GetField<"; - else if (IsStruct(type)) - accessor = "GetStruct<"; - else - accessor = "GetPointer<"; - auto offset_type = GenTypeGet(type, "", "const ", " *", false); - auto call = accessor + offset_type + ">(" + offset_str; - // Default value as second arg for non-pointer types. - if (is_scalar) { call += ", " + GenDefaultConstant(field); } - call += ")"; - - std::string afterptr = " *" + NullableExtension(); - code_.SetValue("FIELD_TYPE", - GenTypeGet(type, " ", "const ", afterptr.c_str(), true)); - code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, call)); - code_.SetValue("NULLABLE_EXT", NullableExtension()); - code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {"; - code_ += " return {{FIELD_VALUE}};"; - code_ += " }"; - } else { - auto wire_type = GenTypeBasic(type, false); - auto face_type = GenTypeBasic(type, true); - auto opt_value = "GetOptional<" + wire_type + ", " + face_type + ">(" + - offset_str + ")"; - code_.SetValue("FIELD_TYPE", GenOptionalDecl(type)); - code_ += " {{FIELD_TYPE}} {{FIELD_NAME}}() const {"; - code_ += " return " + opt_value + ";"; - code_ += " }"; - } - - if (type.base_type == BASE_TYPE_UNION) { GenTableUnionAsGetters(field); } - } - - void GenTableFieldType(const FieldDef &field) { - const auto &type = field.value.type; - const auto offset_str = GenFieldOffsetName(field); - if (!field.IsScalarOptional()) { - std::string afterptr = " *" + NullableExtension(); - code_.SetValue("FIELD_TYPE", - GenTypeGet(type, "", "const ", afterptr.c_str(), true)); - code_ += " {{FIELD_TYPE}}\\"; - } else { - code_.SetValue("FIELD_TYPE", GenOptionalDecl(type)); - code_ += " {{FIELD_TYPE}}\\"; - } - } - - void GenStructFieldType(const FieldDef &field) { - const auto is_array = IsArray(field.value.type); - std::string field_type = - GenTypeGet(field.value.type, "", is_array ? "" : "const ", - is_array ? "" : " &", true); - code_.SetValue("FIELD_TYPE", field_type); - code_ += " {{FIELD_TYPE}}\\"; - } - - void GenFieldTypeHelper(const StructDef &struct_def) { - if (struct_def.fields.vec.empty()) { return; } - code_ += " template<size_t Index>"; - code_ += " using FieldType = \\"; - code_ += "decltype(std::declval<type>().get_field<Index>());"; - } - - void GenIndexBasedFieldGetter(const StructDef &struct_def) { - if (struct_def.fields.vec.empty()) { return; } - code_ += " template<size_t Index>"; - code_ += " auto get_field() const {"; - - size_t index = 0; - bool need_else = false; - // Generate one index-based getter for each field. - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { - // Deprecated fields won't be accessible. - continue; - } - code_.SetValue("FIELD_NAME", Name(field)); - code_.SetValue("FIELD_INDEX", - std::to_string(static_cast<long long>(index++))); - if (need_else) { - code_ += " else \\"; - } else { - code_ += " \\"; - } - need_else = true; - code_ += "if constexpr (Index == {{FIELD_INDEX}}) \\"; - code_ += "return {{FIELD_NAME}}();"; - } - code_ += " else static_assert(Index != Index, \"Invalid Field Index\");"; - code_ += " }"; - } - - // Sample for Vec3: - // - // static constexpr std::array<const char *, 3> field_names = { - // "x", - // "y", - // "z" - // }; - // - void GenFieldNames(const StructDef &struct_def) { - auto non_deprecated_field_count = std::count_if( - struct_def.fields.vec.begin(), struct_def.fields.vec.end(), - [](const FieldDef *field) { return !field->deprecated; }); - code_ += " static constexpr std::array<\\"; - code_.SetValue( - "FIELD_COUNT", - std::to_string(static_cast<long long>(non_deprecated_field_count))); - code_ += "const char *, {{FIELD_COUNT}}> field_names = {\\"; - if (struct_def.fields.vec.empty()) { - code_ += "};"; - return; - } - code_ += ""; - // Generate the field_names elements. - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { - // Deprecated fields won't be accessible. - continue; - } - code_.SetValue("FIELD_NAME", Name(field)); - code_ += " \"{{FIELD_NAME}}\"\\"; - if (it + 1 != struct_def.fields.vec.end()) { code_ += ","; } - } - code_ += "\n };"; - } - - void GenFieldsNumber(const StructDef &struct_def) { - auto non_deprecated_field_count = std::count_if( - struct_def.fields.vec.begin(), struct_def.fields.vec.end(), - [](const FieldDef *field) { return !field->deprecated; }); - code_.SetValue( - "FIELD_COUNT", - std::to_string(static_cast<long long>(non_deprecated_field_count))); - code_ += " static constexpr size_t fields_number = {{FIELD_COUNT}};"; - } - - void GenTraitsStruct(const StructDef &struct_def) { - code_.SetValue( - "FULLY_QUALIFIED_NAME", - struct_def.defined_namespace->GetFullyQualifiedName(Name(struct_def))); - code_ += "struct {{STRUCT_NAME}}::Traits {"; - code_ += " using type = {{STRUCT_NAME}};"; - if (!struct_def.fixed) { - // We have a table and not a struct. - code_ += " static auto constexpr Create = Create{{STRUCT_NAME}};"; - } - if (opts_.cpp_static_reflection) { - code_ += " static constexpr auto name = \"{{STRUCT_NAME}}\";"; - code_ += - " static constexpr auto fully_qualified_name = " - "\"{{FULLY_QUALIFIED_NAME}}\";"; - GenFieldNames(struct_def); - GenFieldTypeHelper(struct_def); - GenFieldsNumber(struct_def); - } - code_ += "};"; - code_ += ""; - } - - void GenTableFieldSetter(const FieldDef &field) { - const auto &type = field.value.type; - const bool is_scalar = IsScalar(type.base_type); - if (is_scalar && IsUnion(type)) - return; // changing of a union's type is forbidden - - auto offset_str = GenFieldOffsetName(field); - if (is_scalar) { - const auto wire_type = GenTypeWire(type, "", false); - code_.SetValue("SET_FN", "SetField<" + wire_type + ">"); - code_.SetValue("OFFSET_NAME", offset_str); - code_.SetValue("FIELD_TYPE", GenTypeBasic(type, true)); - code_.SetValue("FIELD_VALUE", - GenUnderlyingCast(field, false, "_" + Name(field))); - - code_ += - " bool mutate_{{FIELD_NAME}}({{FIELD_TYPE}} " - "_{{FIELD_NAME}}) {"; - if (false == field.IsScalarOptional()) { - code_.SetValue("DEFAULT_VALUE", GenDefaultConstant(field)); - code_ += - " return {{SET_FN}}({{OFFSET_NAME}}, {{FIELD_VALUE}}, " - "{{DEFAULT_VALUE}});"; - } else { - code_ += " return {{SET_FN}}({{OFFSET_NAME}}, {{FIELD_VALUE}});"; - } - code_ += " }"; - } else { - auto postptr = " *" + NullableExtension(); - auto wire_type = GenTypeGet(type, " ", "", postptr.c_str(), true); - std::string accessor = IsStruct(type) ? "GetStruct<" : "GetPointer<"; - auto underlying = accessor + wire_type + ">(" + offset_str + ")"; - code_.SetValue("FIELD_TYPE", wire_type); - code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, underlying)); - - code_ += " {{FIELD_TYPE}}mutable_{{FIELD_NAME}}() {"; - code_ += " return {{FIELD_VALUE}};"; - code_ += " }"; - } - } - - // Generate an accessor struct, builder structs & function for a table. - void GenTable(const StructDef &struct_def) { - if (opts_.generate_object_based_api) { GenNativeTable(struct_def); } - - // Generate an accessor struct, with methods of the form: - // type name() const { return GetField<type>(offset, defaultval); } - GenComment(struct_def.doc_comment); - - code_.SetValue("STRUCT_NAME", Name(struct_def)); - code_ += - "struct {{STRUCT_NAME}} FLATBUFFERS_FINAL_CLASS" - " : private flatbuffers::Table {"; - if (opts_.generate_object_based_api) { - code_ += " typedef {{NATIVE_NAME}} NativeTableType;"; - } - code_ += " typedef {{STRUCT_NAME}}Builder Builder;"; - if (opts_.g_cpp_std >= cpp::CPP_STD_17) { code_ += " struct Traits;"; } - if (opts_.mini_reflect != IDLOptions::kNone) { - code_ += - " static const flatbuffers::TypeTable *MiniReflectTypeTable() {"; - code_ += " return {{STRUCT_NAME}}TypeTable();"; - code_ += " }"; - } - - GenFullyQualifiedNameGetter(struct_def, Name(struct_def)); - - // Generate field id constants. - if (struct_def.fields.vec.size() > 0) { - // We need to add a trailing comma to all elements except the last one as - // older versions of gcc complain about this. - code_.SetValue("SEP", ""); - code_ += - " enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { - // Deprecated fields won't be accessible. - continue; - } - - code_.SetValue("OFFSET_NAME", GenFieldOffsetName(field)); - code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset)); - code_ += "{{SEP}} {{OFFSET_NAME}} = {{OFFSET_VALUE}}\\"; - code_.SetValue("SEP", ",\n"); - } - code_ += ""; - code_ += " };"; - } - - // Generate the accessors. - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { - // Deprecated fields won't be accessible. - continue; - } - - code_.SetValue("FIELD_NAME", Name(field)); - GenTableFieldGetter(field); - if (opts_.mutable_buffer) { GenTableFieldSetter(field); } - - auto nested = field.attributes.Lookup("nested_flatbuffer"); - if (nested) { - std::string qualified_name = nested->constant; - auto nested_root = parser_.LookupStruct(nested->constant); - if (nested_root == nullptr) { - qualified_name = parser_.current_namespace_->GetFullyQualifiedName( - nested->constant); - nested_root = parser_.LookupStruct(qualified_name); - } - FLATBUFFERS_ASSERT(nested_root); // Guaranteed to exist by parser. - (void)nested_root; - code_.SetValue("CPP_NAME", TranslateNameSpace(qualified_name)); - - code_ += " const {{CPP_NAME}} *{{FIELD_NAME}}_nested_root() const {"; - code_ += - " return " - "flatbuffers::GetRoot<{{CPP_NAME}}>({{FIELD_NAME}}()->Data());"; - code_ += " }"; - } - - if (field.flexbuffer) { - code_ += - " flexbuffers::Reference {{FIELD_NAME}}_flexbuffer_root()" - " const {"; - // Both Data() and size() are const-methods, therefore call order - // doesn't matter. - code_ += - " return flexbuffers::GetRoot({{FIELD_NAME}}()->Data(), " - "{{FIELD_NAME}}()->size());"; - code_ += " }"; - } - - // Generate a comparison function for this field if it is a key. - if (field.key) { GenKeyFieldMethods(field); } - } - - if (opts_.cpp_static_reflection) { GenIndexBasedFieldGetter(struct_def); } - - // Generate a verifier function that can check a buffer from an untrusted - // source will never cause reads outside the buffer. - code_ += " bool Verify(flatbuffers::Verifier &verifier) const {"; - code_ += " return VerifyTableStart(verifier)\\"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { continue; } - GenVerifyCall(field, " &&\n "); - } - - code_ += " &&\n verifier.EndTable();"; - code_ += " }"; - - if (opts_.generate_object_based_api) { - // Generate the UnPack() pre declaration. - code_ += " " + TableUnPackSignature(struct_def, true, opts_) + ";"; - code_ += " " + TableUnPackToSignature(struct_def, true, opts_) + ";"; - code_ += " " + TablePackSignature(struct_def, true, opts_) + ";"; - } - - code_ += "};"; // End of table. - code_ += ""; - - // Explicit specializations for union accessors - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated || field.value.type.base_type != BASE_TYPE_UNION) { - continue; - } - - auto u = field.value.type.enum_def; - if (u->uses_multiple_type_instances) continue; - - code_.SetValue("FIELD_NAME", Name(field)); - - for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) { - auto &ev = **u_it; - if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } - - auto full_struct_name = GetUnionElement(ev, false, opts_); - - code_.SetValue( - "U_ELEMENT_TYPE", - WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev))); - code_.SetValue("U_FIELD_TYPE", "const " + full_struct_name + " *"); - code_.SetValue("U_ELEMENT_NAME", full_struct_name); - code_.SetValue("U_FIELD_NAME", Name(field) + "_as_" + Name(ev)); - - // `template<> const T *union_name_as<T>() const` accessor. - code_ += - "template<> " - "inline {{U_FIELD_TYPE}}{{STRUCT_NAME}}::{{FIELD_NAME}}_as" - "<{{U_ELEMENT_NAME}}>() const {"; - code_ += " return {{U_FIELD_NAME}}();"; - code_ += "}"; - code_ += ""; - } - } - - GenBuilders(struct_def); - - if (opts_.generate_object_based_api) { - // Generate a pre-declaration for a CreateX method that works with an - // unpacked C++ object. - code_ += TableCreateSignature(struct_def, true, opts_) + ";"; - code_ += ""; - } - } - - // Generate code to force vector alignment. Return empty string for vector - // that doesn't need alignment code. - std::string GenVectorForceAlign(const FieldDef &field, - const std::string &field_size) { - FLATBUFFERS_ASSERT(IsVector(field.value.type)); - // Get the value of the force_align attribute. - const auto *force_align = field.attributes.Lookup("force_align"); - const int align = force_align ? atoi(force_align->constant.c_str()) : 1; - // Generate code to do force_align for the vector. - if (align > 1) { - const auto vtype = field.value.type.VectorType(); - const auto type = IsStruct(vtype) ? WrapInNameSpace(*vtype.struct_def) - : GenTypeWire(vtype, "", false); - return "_fbb.ForceVectorAlignment(" + field_size + ", sizeof(" + type + - "), " + std::to_string(static_cast<long long>(align)) + ");"; - } - return ""; - } - - void GenBuilders(const StructDef &struct_def) { - code_.SetValue("STRUCT_NAME", Name(struct_def)); - - // Generate a builder struct: - code_ += "struct {{STRUCT_NAME}}Builder {"; - code_ += " typedef {{STRUCT_NAME}} Table;"; - code_ += " flatbuffers::FlatBufferBuilder &fbb_;"; - code_ += " flatbuffers::uoffset_t start_;"; - - bool has_string_or_vector_fields = false; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) continue; - const bool is_scalar = IsScalar(field.value.type.base_type); - const bool is_default_scalar = is_scalar && !field.IsScalarOptional(); - const bool is_string = IsString(field.value.type); - const bool is_vector = IsVector(field.value.type); - if (is_string || is_vector) { has_string_or_vector_fields = true; } - - std::string offset = GenFieldOffsetName(field); - std::string name = GenUnderlyingCast(field, false, Name(field)); - std::string value = is_default_scalar ? GenDefaultConstant(field) : ""; - - // Generate accessor functions of the form: - // void add_name(type name) { - // fbb_.AddElement<type>(offset, name, default); - // } - code_.SetValue("FIELD_NAME", Name(field)); - code_.SetValue("FIELD_TYPE", GenTypeWire(field.value.type, " ", true)); - code_.SetValue("ADD_OFFSET", Name(struct_def) + "::" + offset); - code_.SetValue("ADD_NAME", name); - code_.SetValue("ADD_VALUE", value); - if (is_scalar) { - const auto type = GenTypeWire(field.value.type, "", false); - code_.SetValue("ADD_FN", "AddElement<" + type + ">"); - } else if (IsStruct(field.value.type)) { - code_.SetValue("ADD_FN", "AddStruct"); - } else { - code_.SetValue("ADD_FN", "AddOffset"); - } - - code_ += " void add_{{FIELD_NAME}}({{FIELD_TYPE}}{{FIELD_NAME}}) {"; - code_ += " fbb_.{{ADD_FN}}(\\"; - if (is_default_scalar) { - code_ += "{{ADD_OFFSET}}, {{ADD_NAME}}, {{ADD_VALUE}});"; - } else { - code_ += "{{ADD_OFFSET}}, {{ADD_NAME}});"; - } - code_ += " }"; - } - - // Builder constructor - code_ += - " explicit {{STRUCT_NAME}}Builder(flatbuffers::FlatBufferBuilder " - "&_fbb)"; - code_ += " : fbb_(_fbb) {"; - code_ += " start_ = fbb_.StartTable();"; - code_ += " }"; - - // Finish() function. - code_ += " flatbuffers::Offset<{{STRUCT_NAME}}> Finish() {"; - code_ += " const auto end = fbb_.EndTable(start_);"; - code_ += " auto o = flatbuffers::Offset<{{STRUCT_NAME}}>(end);"; - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (!field.deprecated && field.IsRequired()) { - code_.SetValue("FIELD_NAME", Name(field)); - code_.SetValue("OFFSET_NAME", GenFieldOffsetName(field)); - code_ += " fbb_.Required(o, {{STRUCT_NAME}}::{{OFFSET_NAME}});"; - } - } - code_ += " return o;"; - code_ += " }"; - code_ += "};"; - code_ += ""; - - // Generate a convenient CreateX function that uses the above builder - // to create a table in one go. - code_ += - "inline flatbuffers::Offset<{{STRUCT_NAME}}> " - "Create{{STRUCT_NAME}}("; - code_ += " flatbuffers::FlatBufferBuilder &_fbb\\"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (!field.deprecated) { GenParam(field, false, ",\n "); } - } - code_ += ") {"; - - code_ += " {{STRUCT_NAME}}Builder builder_(_fbb);"; - for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1; - size; size /= 2) { - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - const auto &field = **it; - if (!field.deprecated && (!struct_def.sortbysize || - size == SizeOf(field.value.type.base_type))) { - code_.SetValue("FIELD_NAME", Name(field)); - if (field.IsScalarOptional()) { - code_ += - " if({{FIELD_NAME}}) { " - "builder_.add_{{FIELD_NAME}}(*{{FIELD_NAME}}); }"; - } else { - code_ += " builder_.add_{{FIELD_NAME}}({{FIELD_NAME}});"; - } - } - } - } - code_ += " return builder_.Finish();"; - code_ += "}"; - code_ += ""; - - // Definition for type traits for this table type. This allows querying var- - // ious compile-time traits of the table. - if (opts_.g_cpp_std >= cpp::CPP_STD_17) { GenTraitsStruct(struct_def); } - - // Generate a CreateXDirect function with vector types as parameters - if (opts_.cpp_direct_copy && has_string_or_vector_fields) { - code_ += - "inline flatbuffers::Offset<{{STRUCT_NAME}}> " - "Create{{STRUCT_NAME}}Direct("; - code_ += " flatbuffers::FlatBufferBuilder &_fbb\\"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (!field.deprecated) { GenParam(field, true, ",\n "); } - } - // Need to call "Create" with the struct namespace. - const auto qualified_create_name = - struct_def.defined_namespace->GetFullyQualifiedName("Create"); - code_.SetValue("CREATE_NAME", TranslateNameSpace(qualified_create_name)); - code_ += ") {"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (!field.deprecated) { - code_.SetValue("FIELD_NAME", Name(field)); - if (IsString(field.value.type)) { - if (!field.shared) { - code_.SetValue("CREATE_STRING", "CreateString"); - } else { - code_.SetValue("CREATE_STRING", "CreateSharedString"); - } - code_ += - " auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? " - "_fbb.{{CREATE_STRING}}({{FIELD_NAME}}) : 0;"; - } else if (IsVector(field.value.type)) { - const std::string force_align_code = - GenVectorForceAlign(field, Name(field) + "->size()"); - if (!force_align_code.empty()) { - code_ += " if ({{FIELD_NAME}}) { " + force_align_code + " }"; - } - code_ += " auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? \\"; - const auto vtype = field.value.type.VectorType(); - const auto has_key = TypeHasKey(vtype); - if (IsStruct(vtype)) { - const auto type = WrapInNameSpace(*vtype.struct_def); - code_ += (has_key ? "_fbb.CreateVectorOfSortedStructs<" - : "_fbb.CreateVectorOfStructs<") + - type + ">\\"; - } else if (has_key) { - const auto type = WrapInNameSpace(*vtype.struct_def); - code_ += "_fbb.CreateVectorOfSortedTables<" + type + ">\\"; - } else { - const auto type = - GenTypeWire(vtype, "", VectorElementUserFacing(vtype)); - code_ += "_fbb.CreateVector<" + type + ">\\"; - } - code_ += - has_key ? "({{FIELD_NAME}}) : 0;" : "(*{{FIELD_NAME}}) : 0;"; - } - } - } - code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}("; - code_ += " _fbb\\"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (!field.deprecated) { - code_.SetValue("FIELD_NAME", Name(field)); - code_ += ",\n {{FIELD_NAME}}\\"; - if (IsString(field.value.type) || IsVector(field.value.type)) { - code_ += "__\\"; - } - } - } - code_ += ");"; - code_ += "}"; - code_ += ""; - } - } - - std::string GenUnionUnpackVal(const FieldDef &afield, - const char *vec_elem_access, - const char *vec_type_access) { - auto type_name = WrapInNameSpace(*afield.value.type.enum_def); - return type_name + "Union::UnPack(" + "_e" + vec_elem_access + ", " + - EscapeKeyword(afield.name + UnionTypeFieldSuffix()) + "()" + - vec_type_access + ", _resolver)"; - } - - std::string GenUnpackVal(const Type &type, const std::string &val, - bool invector, const FieldDef &afield) { - switch (type.base_type) { - case BASE_TYPE_STRING: { - if (FlexibleStringConstructor(&afield)) { - return NativeString(&afield) + "(" + val + "->c_str(), " + val + - "->size())"; - } else { - return val + "->str()"; - } - } - case BASE_TYPE_STRUCT: { - if (IsStruct(type)) { - const auto &struct_attrs = type.struct_def->attributes; - const auto native_type = struct_attrs.Lookup("native_type"); - if (native_type) { - std::string unpack_call = "flatbuffers::UnPack"; - const auto pack_name = struct_attrs.Lookup("native_type_pack_name"); - if (pack_name) { unpack_call += pack_name->constant; } - unpack_call += "(*" + val + ")"; - return unpack_call; - } else if (invector || afield.native_inline) { - return "*" + val; - } else { - const auto name = WrapInNameSpace(*type.struct_def); - const auto ptype = GenTypeNativePtr(name, &afield, true); - return ptype + "(new " + name + "(*" + val + "))"; - } - } else { - const auto ptype = GenTypeNativePtr( - WrapNativeNameInNameSpace(*type.struct_def, opts_), &afield, - true); - return ptype + "(" + val + "->UnPack(_resolver))"; - } - } - case BASE_TYPE_UNION: { - return GenUnionUnpackVal( - afield, invector ? "->Get(_i)" : "", - invector ? ("->GetEnum<" + type.enum_def->name + ">(_i)").c_str() - : ""); - } - default: { - return val; - break; - } - } - } - - std::string GenUnpackFieldStatement(const FieldDef &field, - const FieldDef *union_field) { - std::string code; - switch (field.value.type.base_type) { - case BASE_TYPE_VECTOR: { - auto name = Name(field); - if (field.value.type.element == BASE_TYPE_UTYPE) { - name = StripUnionType(Name(field)); - } - code += "{ _o->" + name + ".resize(_e->size()); "; - if (!field.value.type.enum_def && !IsBool(field.value.type.element) && - IsOneByte(field.value.type.element)) { - // For vectors of bytes, std::copy is used to improve performance. - // This doesn't work for: - // - enum types because they have to be explicitly static_cast. - // - vectors of bool, since they are a template specialization. - // - multiple-byte types due to endianness. - code += - "std::copy(_e->begin(), _e->end(), _o->" + name + ".begin()); }"; - } else { - std::string indexing; - if (field.value.type.enum_def) { - indexing += "static_cast<" + - WrapInNameSpace(*field.value.type.enum_def) + ">("; - } - indexing += "_e->Get(_i)"; - if (field.value.type.enum_def) { indexing += ")"; } - if (field.value.type.element == BASE_TYPE_BOOL) { - indexing += " != 0"; - } - // Generate code that pushes data from _e to _o in the form: - // for (uoffset_t i = 0; i < _e->size(); ++i) { - // _o->field.push_back(_e->Get(_i)); - // } - auto access = - field.value.type.element == BASE_TYPE_UTYPE - ? ".type" - : (field.value.type.element == BASE_TYPE_UNION ? ".value" - : ""); - - code += "for (flatbuffers::uoffset_t _i = 0;"; - code += " _i < _e->size(); _i++) { "; - auto cpp_type = field.attributes.Lookup("cpp_type"); - if (cpp_type) { - // Generate code that resolves the cpp pointer type, of the form: - // if (resolver) - // (*resolver)(&_o->field, (hash_value_t)(_e)); - // else - // _o->field = nullptr; - code += "//vector resolver, " + PtrType(&field) + "\n"; - code += "if (_resolver) "; - code += "(*_resolver)"; - code += "(reinterpret_cast<void **>(&_o->" + name + "[_i]" + - access + "), "; - code += - "static_cast<flatbuffers::hash_value_t>(" + indexing + "));"; - if (PtrType(&field) == "naked") { - code += " else "; - code += "_o->" + name + "[_i]" + access + " = nullptr"; - } else { - // code += " else "; - // code += "_o->" + name + "[_i]" + access + " = " + - // GenTypeNativePtr(cpp_type->constant, &field, true) + "();"; - code += "/* else do nothing */"; - } - } else { - code += "_o->" + name + "[_i]" + access + " = "; - code += GenUnpackVal(field.value.type.VectorType(), indexing, true, - field); - } - code += "; } }"; - } - break; - } - case BASE_TYPE_UTYPE: { - FLATBUFFERS_ASSERT(union_field->value.type.base_type == - BASE_TYPE_UNION); - // Generate code that sets the union type, of the form: - // _o->field.type = _e; - code += "_o->" + union_field->name + ".type = _e;"; - break; - } - case BASE_TYPE_UNION: { - // Generate code that sets the union value, of the form: - // _o->field.value = Union::Unpack(_e, field_type(), resolver); - code += "_o->" + Name(field) + ".value = "; - code += GenUnionUnpackVal(field, "", ""); - code += ";"; - break; - } - default: { - auto cpp_type = field.attributes.Lookup("cpp_type"); - if (cpp_type) { - // Generate code that resolves the cpp pointer type, of the form: - // if (resolver) - // (*resolver)(&_o->field, (hash_value_t)(_e)); - // else - // _o->field = nullptr; - code += "//scalar resolver, " + PtrType(&field) + " \n"; - code += "if (_resolver) "; - code += "(*_resolver)"; - code += "(reinterpret_cast<void **>(&_o->" + Name(field) + "), "; - code += "static_cast<flatbuffers::hash_value_t>(_e));"; - if (PtrType(&field) == "naked") { - code += " else "; - code += "_o->" + Name(field) + " = nullptr;"; - } else { - // code += " else "; - // code += "_o->" + Name(field) + " = " + - // GenTypeNativePtr(cpp_type->constant, &field, true) + "();"; - code += "/* else do nothing */;"; - } - } else { - // Generate code for assigning the value, of the form: - // _o->field = value; - code += "_o->" + Name(field) + " = "; - code += GenUnpackVal(field.value.type, "_e", false, field) + ";"; - } - break; - } - } - return code; - } - - std::string GenCreateParam(const FieldDef &field) { - std::string value = "_o->"; - if (field.value.type.base_type == BASE_TYPE_UTYPE) { - value += StripUnionType(Name(field)); - value += ".type"; - } else { - value += Name(field); - } - if (field.value.type.base_type != BASE_TYPE_VECTOR && - field.attributes.Lookup("cpp_type")) { - auto type = GenTypeBasic(field.value.type, false); - value = - "_rehasher ? " - "static_cast<" + - type + ">((*_rehasher)(" + value + GenPtrGet(field) + ")) : 0"; - } - - std::string code; - switch (field.value.type.base_type) { - // String fields are of the form: - // _fbb.CreateString(_o->field) - // or - // _fbb.CreateSharedString(_o->field) - case BASE_TYPE_STRING: { - if (!field.shared) { - code += "_fbb.CreateString("; - } else { - code += "_fbb.CreateSharedString("; - } - code += value; - code.push_back(')'); - - // For optional fields, check to see if there actually is any data - // in _o->field before attempting to access it. If there isn't, - // depending on set_empty_strings_to_null either set it to 0 or an empty - // string. - if (!field.IsRequired()) { - auto empty_value = opts_.set_empty_strings_to_null - ? "0" - : "_fbb.CreateSharedString(\"\")"; - code = value + ".empty() ? " + empty_value + " : " + code; - } - break; - } - // Vector fields come in several flavours, of the forms: - // _fbb.CreateVector(_o->field); - // _fbb.CreateVector((const utype*)_o->field.data(), - // _o->field.size()); _fbb.CreateVectorOfStrings(_o->field) - // _fbb.CreateVectorOfStructs(_o->field) - // _fbb.CreateVector<Offset<T>>(_o->field.size() [&](size_t i) { - // return CreateT(_fbb, _o->Get(i), rehasher); - // }); - case BASE_TYPE_VECTOR: { - auto vector_type = field.value.type.VectorType(); - switch (vector_type.base_type) { - case BASE_TYPE_STRING: { - if (NativeString(&field) == "std::string") { - code += "_fbb.CreateVectorOfStrings(" + value + ")"; - } else { - // Use by-function serialization to emulate - // CreateVectorOfStrings(); this works also with non-std strings. - code += - "_fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>" - " "; - code += "(" + value + ".size(), "; - code += "[](size_t i, _VectorArgs *__va) { "; - code += - "return __va->__fbb->CreateString(__va->_" + value + "[i]);"; - code += " }, &_va )"; - } - break; - } - case BASE_TYPE_STRUCT: { - if (IsStruct(vector_type)) { - const auto &struct_attrs = - field.value.type.struct_def->attributes; - const auto native_type = struct_attrs.Lookup("native_type"); - if (native_type) { - code += "_fbb.CreateVectorOfNativeStructs<"; - code += WrapInNameSpace(*vector_type.struct_def) + ", " + - native_type->constant + ">"; - code += "(" + value; - const auto pack_name = - struct_attrs.Lookup("native_type_pack_name"); - if (pack_name) { - code += ", flatbuffers::Pack" + pack_name->constant; - } - code += ")"; - } else { - code += "_fbb.CreateVectorOfStructs"; - code += "(" + value + ")"; - } - } else { - code += "_fbb.CreateVector<flatbuffers::Offset<"; - code += WrapInNameSpace(*vector_type.struct_def) + ">> "; - code += "(" + value + ".size(), "; - code += "[](size_t i, _VectorArgs *__va) { "; - code += "return Create" + vector_type.struct_def->name; - code += "(*__va->__fbb, __va->_" + value + "[i]" + - GenPtrGet(field) + ", "; - code += "__va->__rehasher); }, &_va )"; - } - break; - } - case BASE_TYPE_BOOL: { - code += "_fbb.CreateVector(" + value + ")"; - break; - } - case BASE_TYPE_UNION: { - code += - "_fbb.CreateVector<flatbuffers::" - "Offset<void>>(" + - value + - ".size(), [](size_t i, _VectorArgs *__va) { " - "return __va->_" + - value + "[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va)"; - break; - } - case BASE_TYPE_UTYPE: { - value = StripUnionType(value); - code += "_fbb.CreateVector<uint8_t>(" + value + - ".size(), [](size_t i, _VectorArgs *__va) { " - "return static_cast<uint8_t>(__va->_" + - value + "[i].type); }, &_va)"; - break; - } - default: { - if (field.value.type.enum_def && - !VectorElementUserFacing(vector_type)) { - // For enumerations, we need to get access to the array data for - // the underlying storage type (eg. uint8_t). - const auto basetype = GenTypeBasic( - field.value.type.enum_def->underlying_type, false); - code += "_fbb.CreateVectorScalarCast<" + basetype + - ">(flatbuffers::data(" + value + "), " + value + - ".size())"; - } else if (field.attributes.Lookup("cpp_type")) { - auto type = GenTypeBasic(vector_type, false); - code += "_fbb.CreateVector<" + type + ">(" + value + ".size(), "; - code += "[](size_t i, _VectorArgs *__va) { "; - code += "return __va->__rehasher ? "; - code += "static_cast<" + type + ">((*__va->__rehasher)"; - code += "(__va->_" + value + "[i]" + GenPtrGet(field) + ")) : 0"; - code += "; }, &_va )"; - } else { - code += "_fbb.CreateVector(" + value + ")"; - } - break; - } - } - - // If set_empty_vectors_to_null option is enabled, for optional fields, - // check to see if there actually is any data in _o->field before - // attempting to access it. - if (opts_.set_empty_vectors_to_null && !field.IsRequired()) { - code = value + ".size() ? " + code + " : 0"; - } - break; - } - case BASE_TYPE_UNION: { - // _o->field.Pack(_fbb); - code += value + ".Pack(_fbb)"; - break; - } - case BASE_TYPE_STRUCT: { - if (IsStruct(field.value.type)) { - const auto &struct_attribs = field.value.type.struct_def->attributes; - const auto native_type = struct_attribs.Lookup("native_type"); - if (native_type) { - code += "flatbuffers::Pack"; - const auto pack_name = - struct_attribs.Lookup("native_type_pack_name"); - if (pack_name) { code += pack_name->constant; } - code += "(" + value + ")"; - } else if (field.native_inline) { - code += "&" + value; - } else { - code += value + " ? " + value + GenPtrGet(field) + " : 0"; - } - } else { - // _o->field ? CreateT(_fbb, _o->field.get(), _rehasher); - const auto type = field.value.type.struct_def->name; - code += value + " ? Create" + type; - code += "(_fbb, " + value + GenPtrGet(field) + ", _rehasher)"; - code += " : 0"; - } - break; - } - default: { - code += value; - break; - } - } - return code; - } - - // Generate code for tables that needs to come after the regular definition. - void GenTablePost(const StructDef &struct_def) { - code_.SetValue("STRUCT_NAME", Name(struct_def)); - code_.SetValue("NATIVE_NAME", - NativeName(Name(struct_def), &struct_def, opts_)); - - if (opts_.generate_object_based_api) { - // Generate the X::UnPack() method. - code_ += - "inline " + TableUnPackSignature(struct_def, false, opts_) + " {"; - - if (opts_.g_cpp_std == cpp::CPP_STD_X0) { - auto native_name = WrapNativeNameInNameSpace(struct_def, parser_.opts); - code_.SetValue("POINTER_TYPE", - GenTypeNativePtr(native_name, nullptr, false)); - code_ += - " {{POINTER_TYPE}} _o = {{POINTER_TYPE}}(new {{NATIVE_NAME}}());"; - } else if (opts_.g_cpp_std == cpp::CPP_STD_11) { - code_ += - " auto _o = std::unique_ptr<{{NATIVE_NAME}}>(new " - "{{NATIVE_NAME}}());"; - } else { - code_ += " auto _o = std::make_unique<{{NATIVE_NAME}}>();"; - } - code_ += " UnPackTo(_o.get(), _resolver);"; - code_ += " return _o.release();"; - code_ += "}"; - code_ += ""; - code_ += - "inline " + TableUnPackToSignature(struct_def, false, opts_) + " {"; - code_ += " (void)_o;"; - code_ += " (void)_resolver;"; - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { continue; } - - // Assign a value from |this| to |_o|. Values from |this| are stored - // in a variable |_e| by calling this->field_type(). The value is then - // assigned to |_o| using the GenUnpackFieldStatement. - const bool is_union = field.value.type.base_type == BASE_TYPE_UTYPE; - const auto statement = - GenUnpackFieldStatement(field, is_union ? *(it + 1) : nullptr); - - code_.SetValue("FIELD_NAME", Name(field)); - auto prefix = " { auto _e = {{FIELD_NAME}}(); "; - auto check = IsScalar(field.value.type.base_type) ? "" : "if (_e) "; - auto postfix = " }"; - code_ += std::string(prefix) + check + statement + postfix; - } - code_ += "}"; - code_ += ""; - - // Generate the X::Pack member function that simply calls the global - // CreateX function. - code_ += "inline " + TablePackSignature(struct_def, false, opts_) + " {"; - code_ += " return Create{{STRUCT_NAME}}(_fbb, _o, _rehasher);"; - code_ += "}"; - code_ += ""; - - // Generate a CreateX method that works with an unpacked C++ object. - code_ += - "inline " + TableCreateSignature(struct_def, false, opts_) + " {"; - code_ += " (void)_rehasher;"; - code_ += " (void)_o;"; - - code_ += - " struct _VectorArgs " - "{ flatbuffers::FlatBufferBuilder *__fbb; " - "const " + - NativeName(Name(struct_def), &struct_def, opts_) + - "* __o; " - "const flatbuffers::rehasher_function_t *__rehasher; } _va = { " - "&_fbb, _o, _rehasher}; (void)_va;"; - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) { continue; } - if (IsVector(field.value.type)) { - const std::string force_align_code = - GenVectorForceAlign(field, "_o->" + Name(field) + ".size()"); - if (!force_align_code.empty()) { code_ += " " + force_align_code; } - } - code_ += " auto _" + Name(field) + " = " + GenCreateParam(field) + ";"; - } - // Need to call "Create" with the struct namespace. - const auto qualified_create_name = - struct_def.defined_namespace->GetFullyQualifiedName("Create"); - code_.SetValue("CREATE_NAME", TranslateNameSpace(qualified_create_name)); - - code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}("; - code_ += " _fbb\\"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) { continue; } - - bool pass_by_address = false; - if (field.value.type.base_type == BASE_TYPE_STRUCT) { - if (IsStruct(field.value.type)) { - auto native_type = - field.value.type.struct_def->attributes.Lookup("native_type"); - if (native_type) { pass_by_address = true; } - } - } - - // Call the CreateX function using values from |_o|. - if (pass_by_address) { - code_ += ",\n &_" + Name(field) + "\\"; - } else { - code_ += ",\n _" + Name(field) + "\\"; - } - } - code_ += ");"; - code_ += "}"; - code_ += ""; - } - } - - static void GenPadding( - const FieldDef &field, std::string *code_ptr, int *id, - const std::function<void(int bits, std::string *code_ptr, int *id)> &f) { - if (field.padding) { - for (int i = 0; i < 4; i++) { - if (static_cast<int>(field.padding) & (1 << i)) { - f((1 << i) * 8, code_ptr, id); - } - } - FLATBUFFERS_ASSERT(!(field.padding & ~0xF)); - } - } - - static void PaddingDefinition(int bits, std::string *code_ptr, int *id) { - *code_ptr += " int" + NumToString(bits) + "_t padding" + - NumToString((*id)++) + "__;"; - } - - static void PaddingInitializer(int bits, std::string *code_ptr, int *id) { - (void)bits; - if (!code_ptr->empty()) *code_ptr += ",\n "; - *code_ptr += "padding" + NumToString((*id)++) + "__(0)"; - } - - static void PaddingNoop(int bits, std::string *code_ptr, int *id) { - (void)bits; - if (!code_ptr->empty()) *code_ptr += '\n'; - *code_ptr += " (void)padding" + NumToString((*id)++) + "__;"; - } - - void GenStructDefaultConstructor(const StructDef &struct_def) { - std::string init_list; - std::string body; - bool first_in_init_list = true; - int padding_initializer_id = 0; - int padding_body_id = 0; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto field = *it; - const auto field_name = field->name + "_"; - - if (first_in_init_list) { - first_in_init_list = false; - } else { - init_list += ","; - init_list += "\n "; - } - - init_list += field_name; - if (IsStruct(field->value.type) || IsArray(field->value.type)) { - // this is either default initialization of struct - // or - // implicit initialization of array - // for each object in array it: - // * sets it as zeros for POD types (integral, floating point, etc) - // * calls default constructor for classes/structs - init_list += "()"; - } else { - init_list += "(0)"; - } - if (field->padding) { - GenPadding(*field, &init_list, &padding_initializer_id, - PaddingInitializer); - GenPadding(*field, &body, &padding_body_id, PaddingNoop); - } - } - - if (init_list.empty()) { - code_ += " {{STRUCT_NAME}}()"; - code_ += " {}"; - } else { - code_.SetValue("INIT_LIST", init_list); - code_ += " {{STRUCT_NAME}}()"; - code_ += " : {{INIT_LIST}} {"; - if (!body.empty()) { code_ += body; } - code_ += " }"; - } - } - - void GenStructConstructor(const StructDef &struct_def, - GenArrayArgMode array_mode) { - std::string arg_list; - std::string init_list; - int padding_id = 0; - auto first = struct_def.fields.vec.begin(); - // skip arrays if generate ctor without array assignment - const auto init_arrays = (array_mode != kArrayArgModeNone); - 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; - const auto is_array = IsArray(type); - const auto arg_name = "_" + Name(field); - if (!is_array || init_arrays) { - if (it != first && !arg_list.empty()) { arg_list += ", "; } - arg_list += !is_array ? GenTypeGet(type, " ", "const ", " &", true) - : GenTypeSpan(type, true, type.fixed_length); - arg_list += arg_name; - } - // skip an array with initialization from span - if (false == (is_array && init_arrays)) { - if (it != first && !init_list.empty()) { init_list += ",\n "; } - init_list += Name(field) + "_"; - if (IsScalar(type.base_type)) { - auto scalar_type = GenUnderlyingCast(field, false, arg_name); - init_list += "(flatbuffers::EndianScalar(" + scalar_type + "))"; - } else { - FLATBUFFERS_ASSERT((is_array && !init_arrays) || IsStruct(type)); - if (!is_array) - init_list += "(" + arg_name + ")"; - else - init_list += "()"; - } - } - if (field.padding) - GenPadding(field, &init_list, &padding_id, PaddingInitializer); - } - - if (!arg_list.empty()) { - code_.SetValue("ARG_LIST", arg_list); - code_.SetValue("INIT_LIST", init_list); - if (!init_list.empty()) { - code_ += " {{STRUCT_NAME}}({{ARG_LIST}})"; - code_ += " : {{INIT_LIST}} {"; - } else { - code_ += " {{STRUCT_NAME}}({{ARG_LIST}}) {"; - } - padding_id = 0; - 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 (IsArray(type) && init_arrays) { - const auto &element_type = type.VectorType(); - const auto is_enum = IsEnum(element_type); - FLATBUFFERS_ASSERT( - (IsScalar(element_type.base_type) || IsStruct(element_type)) && - "invalid declaration"); - const auto face_type = GenTypeGet(type, " ", "", "", is_enum); - std::string get_array = - is_enum ? "CastToArrayOfEnum<" + face_type + ">" : "CastToArray"; - const auto field_name = Name(field) + "_"; - const auto arg_name = "_" + Name(field); - code_ += " flatbuffers::" + get_array + "(" + field_name + - ").CopyFromSpan(" + arg_name + ");"; - } - if (field.padding) { - std::string padding; - GenPadding(field, &padding, &padding_id, PaddingNoop); - code_ += padding; - } - } - code_ += " }"; - } - } - - void GenArrayAccessor(const Type &type, bool mutable_accessor) { - FLATBUFFERS_ASSERT(IsArray(type)); - const auto is_enum = IsEnum(type.VectorType()); - // The Array<bool,N> is a tricky case, like std::vector<bool>. - // It requires a specialization of Array class. - // Generate Array<uint8_t> for Array<bool>. - const auto face_type = GenTypeGet(type, " ", "", "", is_enum); - std::string ret_type = "flatbuffers::Array<" + face_type + ", " + - NumToString(type.fixed_length) + ">"; - if (mutable_accessor) - code_ += " " + ret_type + " *mutable_{{FIELD_NAME}}() {"; - else - code_ += " const " + ret_type + " *{{FIELD_NAME}}() const {"; - - std::string get_array = - is_enum ? "CastToArrayOfEnum<" + face_type + ">" : "CastToArray"; - code_ += " return &flatbuffers::" + get_array + "({{FIELD_VALUE}});"; - code_ += " }"; - } - - // Generate an accessor struct with constructor for a flatbuffers struct. - void GenStruct(const StructDef &struct_def) { - // Generate an accessor struct, with private variables of the form: - // type name_; - // Generates manual padding and alignment. - // Variables are private because they contain little endian data on all - // platforms. - GenComment(struct_def.doc_comment); - code_.SetValue("ALIGN", NumToString(struct_def.minalign)); - code_.SetValue("STRUCT_NAME", Name(struct_def)); - - code_ += - "FLATBUFFERS_MANUALLY_ALIGNED_STRUCT({{ALIGN}}) " - "{{STRUCT_NAME}} FLATBUFFERS_FINAL_CLASS {"; - code_ += " private:"; - - int padding_id = 0; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - const auto &field_type = field.value.type; - code_.SetValue("FIELD_TYPE", GenTypeGet(field_type, " ", "", " ", false)); - code_.SetValue("FIELD_NAME", Name(field)); - code_.SetValue("ARRAY", - IsArray(field_type) - ? "[" + NumToString(field_type.fixed_length) + "]" - : ""); - code_ += (" {{FIELD_TYPE}}{{FIELD_NAME}}_{{ARRAY}};"); - - if (field.padding) { - std::string padding; - GenPadding(field, &padding, &padding_id, PaddingDefinition); - code_ += padding; - } - } - - // Generate GetFullyQualifiedName - code_ += ""; - code_ += " public:"; - - if (opts_.g_cpp_std >= cpp::CPP_STD_17) { code_ += " struct Traits;"; } - - // Make TypeTable accessible via the generated struct. - if (opts_.mini_reflect != IDLOptions::kNone) { - code_ += - " static const flatbuffers::TypeTable *MiniReflectTypeTable() {"; - code_ += " return {{STRUCT_NAME}}TypeTable();"; - code_ += " }"; - } - - GenFullyQualifiedNameGetter(struct_def, Name(struct_def)); - - // Generate a default constructor. - GenStructDefaultConstructor(struct_def); - - // Generate a constructor that takes all fields as arguments, - // excluding arrays. - GenStructConstructor(struct_def, kArrayArgModeNone); - - auto arrays_num = std::count_if(struct_def.fields.vec.begin(), - struct_def.fields.vec.end(), - [](const flatbuffers::FieldDef *fd) { - return IsArray(fd->value.type); - }); - if (arrays_num > 0) { - GenStructConstructor(struct_def, kArrayArgModeSpanStatic); - } - - // Generate accessor methods of the form: - // type name() const { return flatbuffers::EndianScalar(name_); } - 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; - const auto is_scalar = IsScalar(type.base_type); - const auto is_array = IsArray(type); - - const auto field_type = GenTypeGet(type, " ", is_array ? "" : "const ", - is_array ? "" : " &", true); - auto member = Name(field) + "_"; - auto value = - is_scalar ? "flatbuffers::EndianScalar(" + member + ")" : member; - - code_.SetValue("FIELD_NAME", Name(field)); - code_.SetValue("FIELD_TYPE", field_type); - code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, value)); - - GenComment(field.doc_comment, " "); - - // Generate a const accessor function. - if (is_array) { - GenArrayAccessor(type, false); - } else { - code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {"; - code_ += " return {{FIELD_VALUE}};"; - code_ += " }"; - } - - // Generate a mutable accessor function. - if (opts_.mutable_buffer) { - auto mut_field_type = - GenTypeGet(type, " ", "", is_array ? "" : " &", true); - code_.SetValue("FIELD_TYPE", mut_field_type); - if (is_scalar) { - code_.SetValue("ARG", GenTypeBasic(type, true)); - code_.SetValue("FIELD_VALUE", - GenUnderlyingCast(field, false, "_" + Name(field))); - - code_ += " void mutate_{{FIELD_NAME}}({{ARG}} _{{FIELD_NAME}}) {"; - code_ += - " flatbuffers::WriteScalar(&{{FIELD_NAME}}_, " - "{{FIELD_VALUE}});"; - code_ += " }"; - } else if (is_array) { - GenArrayAccessor(type, true); - } else { - code_ += " {{FIELD_TYPE}}mutable_{{FIELD_NAME}}() {"; - code_ += " return {{FIELD_VALUE}};"; - code_ += " }"; - } - } - - // Generate a comparison function for this field if it is a key. - if (field.key) { GenKeyFieldMethods(field); } - } - code_.SetValue("NATIVE_NAME", Name(struct_def)); - GenOperatorNewDelete(struct_def); - - if (opts_.cpp_static_reflection) { GenIndexBasedFieldGetter(struct_def); } - - code_ += "};"; - - code_.SetValue("STRUCT_BYTE_SIZE", NumToString(struct_def.bytesize)); - code_ += "FLATBUFFERS_STRUCT_END({{STRUCT_NAME}}, {{STRUCT_BYTE_SIZE}});"; - if (opts_.gen_compare) GenCompareOperator(struct_def, "()"); - code_ += ""; - - // Definition for type traits for this table type. This allows querying var- - // ious compile-time traits of the table. - if (opts_.g_cpp_std >= cpp::CPP_STD_17) { GenTraitsStruct(struct_def); } - } - - // Set up the correct namespace. Only open a namespace if the existing one is - // different (closing/opening only what is necessary). - // - // The file must start and end with an empty (or null) namespace so that - // namespaces are properly opened and closed. - void SetNameSpace(const Namespace *ns) { - if (cur_name_space_ == ns) { return; } - - // Compute the size of the longest common namespace prefix. - // If cur_name_space is A::B::C::D and ns is A::B::E::F::G, - // the common prefix is A::B:: and we have old_size = 4, new_size = 5 - // and common_prefix_size = 2 - size_t old_size = cur_name_space_ ? cur_name_space_->components.size() : 0; - size_t new_size = ns ? ns->components.size() : 0; - - size_t common_prefix_size = 0; - while (common_prefix_size < old_size && common_prefix_size < new_size && - ns->components[common_prefix_size] == - cur_name_space_->components[common_prefix_size]) { - common_prefix_size++; - } - - // Close cur_name_space in reverse order to reach the common prefix. - // In the previous example, D then C are closed. - for (size_t j = old_size; j > common_prefix_size; --j) { - code_ += "} // namespace " + cur_name_space_->components[j - 1]; - } - if (old_size != common_prefix_size) { code_ += ""; } - - // open namespace parts to reach the ns namespace - // in the previous example, E, then F, then G are opened - for (auto j = common_prefix_size; j != new_size; ++j) { - code_ += "namespace " + ns->components[j] + " {"; - } - if (new_size != common_prefix_size) { code_ += ""; } - - cur_name_space_ = ns; - } -}; - -} // namespace cpp - -bool GenerateCPP(const Parser &parser, const std::string &path, - const std::string &file_name) { - cpp::IDLOptionsCpp opts(parser.opts); - // The '--cpp_std' argument could be extended (like ASAN): - // Example: "flatc --cpp_std c++17:option1:option2". - auto cpp_std = !opts.cpp_std.empty() ? opts.cpp_std : "C++11"; - std::transform(cpp_std.begin(), cpp_std.end(), cpp_std.begin(), CharToUpper); - if (cpp_std == "C++0X") { - opts.g_cpp_std = cpp::CPP_STD_X0; - opts.g_only_fixed_enums = false; - } else if (cpp_std == "C++11") { - // Use the standard C++11 code generator. - opts.g_cpp_std = cpp::CPP_STD_11; - opts.g_only_fixed_enums = true; - } else if (cpp_std == "C++17") { - opts.g_cpp_std = cpp::CPP_STD_17; - // With c++17 generate strong enums only. - opts.scoped_enums = true; - // By default, prefixed_enums==true, reset it. - opts.prefixed_enums = false; - } else { - LogCompilerError("Unknown value of the '--cpp-std' switch: " + - opts.cpp_std); - return false; - } - // The opts.scoped_enums has priority. - opts.g_only_fixed_enums |= opts.scoped_enums; - - if (opts.cpp_static_reflection && opts.g_cpp_std < cpp::CPP_STD_17) { - LogCompilerError( - "--cpp-static-reflection requires using --cpp-std at \"C++17\" or " - "higher."); - return false; - } - - cpp::CppGenerator generator(parser, path, file_name, opts); - return generator.generate(); -} - -std::string CPPMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name) { - const auto filebase = - flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); - cpp::CppGenerator geneartor(parser, path, file_name, parser.opts); - const auto included_files = parser.GetIncludedFilesRecursive(file_name); - std::string make_rule = - geneartor.GeneratedFileName(path, filebase, parser.opts) + ": "; - for (auto it = included_files.begin(); it != included_files.end(); ++it) { - make_rule += " " + *it; - } - return make_rule; -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_cpp_yandex_maps_iter.cpp b/contrib/libs/flatbuffers/src/idl_gen_cpp_yandex_maps_iter.cpp deleted file mode 100644 index 1ba2ef3e4a..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_cpp_yandex_maps_iter.cpp +++ /dev/null @@ -1,731 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include <unordered_set> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/flatc.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -// Pedantic warning free version of toupper(). -inline char ToUpper(char c) { - return static_cast<char>(::toupper(static_cast<unsigned char>(c))); -} - -static std::string GeneratedIterFileName(const std::string &path, - const std::string &file_name) { - return path + file_name + ".iter.fbs.h"; -} - -namespace cpp_yandex_maps_iter { -class CppIterGenerator : public BaseGenerator { - public: - CppIterGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", "::", "h"), - cur_name_space_(nullptr) { - static const char *const keywords[] = { - "alignas", - "alignof", - "and", - "and_eq", - "asm", - "atomic_cancel", - "atomic_commit", - "atomic_noexcept", - "auto", - "bitand", - "bitor", - "bool", - "break", - "case", - "catch", - "char", - "char16_t", - "char32_t", - "class", - "compl", - "concept", - "const", - "constexpr", - "const_cast", - "continue", - "co_await", - "co_return", - "co_yield", - "decltype", - "default", - "delete", - "do", - "double", - "dynamic_cast", - "else", - "enum", - "explicit", - "export", - "extern", - "false", - "float", - "for", - "friend", - "goto", - "if", - "import", - "inline", - "int", - "long", - "module", - "mutable", - "namespace", - "new", - "noexcept", - "not", - "not_eq", - "nullptr", - "operator", - "or", - "or_eq", - "private", - "protected", - "public", - "register", - "reinterpret_cast", - "requires", - "return", - "short", - "signed", - "sizeof", - "static", - "static_assert", - "static_cast", - "struct", - "switch", - "synchronized", - "template", - "this", - "thread_local", - "throw", - "true", - "try", - "typedef", - "typeid", - "typename", - "union", - "unsigned", - "using", - "virtual", - "void", - "volatile", - "wchar_t", - "while", - "xor", - "xor_eq", - nullptr, - }; - for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw); - } - - std::string GenIncludeGuard() const { - // Generate include guard. - std::string guard = file_name_; - // Remove any non-alpha-numeric characters that may appear in a filename. - struct IsAlnum { - bool operator()(char c) const { return !isalnum(c); } - }; - guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()), - guard.end()); - guard = "FLATBUFFERS_GENERATED_" + guard; - guard += "_"; - // For further uniqueness, also add the namespace. - auto name_space = parser_.current_namespace_; - for (auto it = name_space->components.begin(); - it != name_space->components.end(); ++it) { - guard += *it + "_"; - } - guard += "ITER_"; - guard += "H_"; - std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper); - return guard; - } - - void GenIncludeDependencies() { - int num_includes = 0; - for (auto it = parser_.native_included_files_.begin(); - it != parser_.native_included_files_.end(); ++it) { - code_ += "#include \"" + *it + "\""; - num_includes++; - } - for (auto it = parser_.included_files_.begin(); - it != parser_.included_files_.end(); ++it) { - if (it->second.empty()) continue; - auto noext = flatbuffers::StripExtension(it->second); - auto basename = flatbuffers::StripPath(noext); - - code_ += "#include \"" + parser_.opts.include_prefix + - (parser_.opts.keep_include_path ? noext : basename) + - ".iter.fbs.h\""; - num_includes++; - } - if (num_includes) code_ += ""; - } - - std::string EscapeKeyword(const std::string &name) const { - return keywords_.find(name) == keywords_.end() ? name : name + "_"; - } - - std::string Name(const Definition &def) const { - return EscapeKeyword(def.name); - } - - std::string Name(const EnumVal &ev) const { return EscapeKeyword(ev.name); } - - // Iterate through all definitions we haven't generate code for (enums, - // structs, and tables) and output them to a single file. - bool generate() { - code_.Clear(); - code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; - - const auto include_guard = GenIncludeGuard(); - code_ += "#ifndef " + include_guard; - code_ += "#define " + include_guard; - code_ += ""; - - if (parser_.opts.gen_nullable) { - code_ += "#pragma clang system_header\n\n"; - } - - code_ += "#include \"" + file_name_ + ".fbs.h\""; - code_ += "#include \"contrib/libs/flatbuffers/include/flatbuffers/flatbuffers_iter.h\""; - code_ += ""; - - if (parser_.opts.include_dependence_headers) { GenIncludeDependencies(); } - - FLATBUFFERS_ASSERT(!cur_name_space_); - - // Generate forward declarations for all structs/tables, since they may - // have circular references. - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.generated && !struct_def.fixed) { - SetNameSpace(struct_def.defined_namespace); - code_ += "template <typename Iter>"; - code_ += "struct " + Name(struct_def) + ";"; - code_ += ""; - } - } - - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.fixed && !struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - GenTable(struct_def); - } - } - - // Generate convenient global helper functions: - if (parser_.root_struct_def_ && !parser_.root_struct_def_->fixed) { - auto &struct_def = *parser_.root_struct_def_; - SetNameSpace(struct_def.defined_namespace); - auto name = Name(struct_def); - auto qualified_name = cur_name_space_->GetFullyQualifiedName(name); - auto cpp_name = TranslateNameSpace(qualified_name, true); - const auto cpp_non_iter_name = TranslateNameSpace(qualified_name); - const auto cpp_non_iter_getter = TranslateNameSpace( - parser_.namespaces_.back()->GetFullyQualifiedName("Get"+name)); - - code_.SetValue("STRUCT_NAME", name); - code_.SetValue("CPP_NAME", cpp_name); - code_.SetValue("CPP_NON_ITER_NAME", cpp_non_iter_name); - code_.SetValue("CPP_NON_ITER_GETTER", cpp_non_iter_getter); - - // The root datatype accessor: - code_ += "template <typename Iter>"; - code_ += "inline \\"; - code_ += "std::optional<{{CPP_NAME}}<Iter>> Get{{STRUCT_NAME}}(const Iter& buf) {"; - code_ += " return yandex::maps::flatbuffers_iter::GetRoot<{{CPP_NAME}}<Iter>, Iter>(buf);"; - code_ += "}"; - code_ += ""; - - // The non_iter datatype accessor: - code_ += "inline \\"; - code_ += "const {{CPP_NON_ITER_NAME}} *Get{{STRUCT_NAME}}(const char *buf) {"; - code_ += " return {{CPP_NON_ITER_GETTER}}(buf);"; - code_ += "}"; - code_ += ""; - - if (parser_.file_identifier_.length()) { - // Return the identifier - code_ += "inline const char *{{STRUCT_NAME}}Identifier() {"; - code_ += " return \"" + parser_.file_identifier_ + "\";"; - code_ += "}"; - code_ += ""; - - // Check if a buffer has the identifier. - code_ += "template <typename Iter>"; - code_ += "inline \\"; - code_ += "bool {{STRUCT_NAME}}BufferHasIdentifier(const Iter& buf) {"; - code_ += " return yandex::maps::flatbuffers_iter::BufferHasIdentifier("; - code_ += " buf, {{STRUCT_NAME}}Identifier());"; - code_ += "}"; - code_ += ""; - } - - // The root verifier. - if (parser_.file_identifier_.length()) { - code_.SetValue("ID", name + "Identifier()"); - } else { - code_.SetValue("ID", "nullptr"); - } - - code_ += "template <typename Iter>"; - code_ += "inline bool Verify{{STRUCT_NAME}}Buffer("; - code_ += " yandex::maps::flatbuffers_iter::Verifier<Iter> &verifier) {"; - code_ += " return verifier.template VerifyBuffer<{{CPP_NAME}}<Iter>>({{ID}});"; - code_ += "}"; - code_ += ""; - - if (parser_.file_extension_.length()) { - // Return the extension - code_ += "inline const char *{{STRUCT_NAME}}Extension() {"; - code_ += " return \"" + parser_.file_extension_ + "\";"; - code_ += "}"; - code_ += ""; - } - } - - if (cur_name_space_) SetNameSpace(nullptr); - - // Close the include guard. - code_ += "#endif // " + include_guard; - - const auto file_path = GeneratedIterFileName(path_, file_name_); - const auto final_code = code_.ToString(); - return SaveFile(file_path.c_str(), final_code, false); - } - - private: - CodeWriter code_; - - std::unordered_set<std::string> keywords_; - - // This tracks the current namespace so we can insert namespace declarations. - const Namespace *cur_name_space_; - - const Namespace *CurrentNameSpace() const { return cur_name_space_; } - -// Ensure that a type is prefixed with its namespace whenever it is used -// outside of its namespace. - std::string WrapInNameSpace(const Namespace *ns, - const std::string &name, bool needIter = false) const { - if (CurrentNameSpace() == ns) return name; - std::string qualified_name = qualifying_start_; - for (auto it = ns->components.begin(); it != ns->components.end(); ++it) - qualified_name += *it + qualifying_separator_; - if (needIter) - qualified_name += "iter" + qualifying_separator_; - return qualified_name + name; - } - - std::string WrapInNameSpace(const Definition &def, bool needIter = false) const { - return WrapInNameSpace(def.defined_namespace, def.name, needIter); - } - - // Translates a qualified name in flatbuffer text format to the same name in - // the equivalent C++ namespace. - static std::string TranslateNameSpace(const std::string &qualified_name, bool needIter = false) { - std::string cpp_qualified_name = qualified_name; - size_t start_pos = 0; - while ((start_pos = cpp_qualified_name.find(".", start_pos)) != - std::string::npos) { - cpp_qualified_name.replace(start_pos, 1, "::"); - } - if (needIter) - { - start_pos = cpp_qualified_name.rfind("::"); - if (start_pos != std::string::npos) - cpp_qualified_name.replace(start_pos, 2, "::iter::"); - } - return cpp_qualified_name; - } - - void GenComment(const std::vector<std::string> &dc, const char *prefix = "") { - std::string text; - ::flatbuffers::GenComment(dc, &text, nullptr, prefix); - code_ += text + "\\"; - } - - // Return a C++ type from the table in idl.h - std::string GenTypeBasic(const Type &type, bool user_facing_type) const { - // clang-format off - static const char * const ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - #CTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - if (user_facing_type) { - if (type.enum_def) return WrapInNameSpace(*type.enum_def); - if (type.base_type == BASE_TYPE_BOOL) return "bool"; - } - return ctypename[type.base_type]; - } - - // Return a C++ pointer type, specialized to the actual struct/table types, - // and vector element types. - std::string GenTypePointer(const Type &type) const { - switch (type.base_type) { - case BASE_TYPE_STRING: { - return "yandex::maps::flatbuffers_iter::String<Iter>"; - } - case BASE_TYPE_VECTOR: { - const auto type_name = GenTypeWire(type.VectorType(), "", false); - return "yandex::maps::flatbuffers_iter::Vector<" + type_name + ", Iter>"; - } - case BASE_TYPE_STRUCT: { - if (IsStruct(type)) - return WrapInNameSpace(*type.struct_def, !type.struct_def->fixed); - return WrapInNameSpace(*type.struct_def, !type.struct_def->fixed) + "<Iter>"; - } - case BASE_TYPE_UNION: - // fall through - default: { return "void"; } - } - } - - // Return a C++ type for any type (scalar/pointer) specifically for - // building a flatbuffer. - std::string GenTypeWire(const Type &type, const char *postfix, - bool user_facing_type) const { - if (IsScalar(type.base_type)) { - return GenTypeBasic(type, user_facing_type) + postfix; - } else if (IsStruct(type)) { - return GenTypePointer(type); - } else { - return "yandex::maps::flatbuffers_iter::Offset<" + GenTypePointer(type) + ">" + postfix; - } - } - - // Return a C++ type for any type (scalar/pointer) that reflects its - // serialized size. - std::string GenTypeSize(const Type &type) const { - if (IsScalar(type.base_type)) { - return GenTypeBasic(type, false); - } else if (IsStruct(type)) { - return GenTypePointer(type); - } else { - return "yandex::maps::flatbuffers_iter::uoffset_t"; - } - } - - // Return a C++ type for any type (scalar/pointer) specifically for - // using a flatbuffer. - std::string GenTypeGet(const Type &type, const char *afterbasic, - const char *beforeptr, const char *afterptr, - bool user_facing_type) { - if (IsScalar(type.base_type)) { - return GenTypeBasic(type, user_facing_type) + afterbasic; - } else { - return beforeptr + GenTypePointer(type) + afterptr; - } - } - - // Generates a value with optionally a cast applied if the field has a - // different underlying type from its interface type (currently only the - // case for enums. "from" specify the direction, true meaning from the - // underlying type to the interface type. - std::string GenUnderlyingCast(const FieldDef &field, bool from, - const std::string &val) { - if (from && field.value.type.base_type == BASE_TYPE_BOOL) { - return val + " != 0"; - } else if ((field.value.type.enum_def && - IsScalar(field.value.type.base_type)) || - field.value.type.base_type == BASE_TYPE_BOOL) { - return "static_cast<" + GenTypeBasic(field.value.type, from) + ">(" + - val + ")"; - } else { - return val; - } - } - - std::string GenFieldOffsetName(const FieldDef &field) { - std::string uname = Name(field); - std::transform(uname.begin(), uname.end(), uname.begin(), ToUpper); - return "VT_" + uname; - } - - std::string GenDefaultConstant(const FieldDef &field) { - return field.value.type.base_type == BASE_TYPE_FLOAT - ? field.value.constant + "f" - : field.value.constant; - } - - // Generate the code to call the appropriate Verify function(s) for a field. - void GenVerifyCall(const FieldDef &field, const char *prefix) { - code_.SetValue("PRE", prefix); - code_.SetValue("NAME", Name(field)); - code_.SetValue("REQUIRED", field.IsRequired() ? "Required" : ""); - code_.SetValue("SIZE", GenTypeSize(field.value.type)); - code_.SetValue("OFFSET", GenFieldOffsetName(field)); - code_ += "{{PRE}}this->template VerifyField{{REQUIRED}}<{{SIZE}}>(verifier, {{OFFSET}})\\"; - - switch (field.value.type.base_type) { - case BASE_TYPE_UNION: { - code_.SetValue("ENUM_NAME", field.value.type.enum_def->name); - code_.SetValue("SUFFIX", UnionTypeFieldSuffix()); - code_ += - "{{PRE}}Verify{{ENUM_NAME}}(verifier, {{NAME}}(), " - "{{NAME}}{{SUFFIX}}())\\"; - break; - } - case BASE_TYPE_STRUCT: { - if (!field.value.type.struct_def->fixed) { - code_ += "{{PRE}}verifier.VerifyTable({{NAME}}())\\"; - } - break; - } - case BASE_TYPE_STRING: { - code_ += "{{PRE}}verifier.Verify({{NAME}}())\\"; - break; - } - case BASE_TYPE_VECTOR: { - code_ += "{{PRE}}verifier.Verify({{NAME}}())\\"; - - switch (field.value.type.element) { - case BASE_TYPE_STRING: { - code_ += "{{PRE}}verifier.VerifyVectorOfStrings({{NAME}}())\\"; - break; - } - case BASE_TYPE_STRUCT: { - if (!field.value.type.struct_def->fixed) { - code_ += "{{PRE}}verifier.VerifyVectorOfTables({{NAME}}())\\"; - } - break; - } - case BASE_TYPE_UNION: { - code_.SetValue("ENUM_NAME", field.value.type.enum_def->name); - code_ += - "{{PRE}}Verify{{ENUM_NAME}}Vector(verifier, {{NAME}}(), " - "{{NAME}}_type())\\"; - break; - } - default: break; - } - break; - } - default: { break; } - } - } - - // Generate CompareWithValue method for a key field. - void GenKeyFieldMethods(const FieldDef &field) { - FLATBUFFERS_ASSERT(field.key); - const bool is_string = (field.value.type.base_type == BASE_TYPE_STRING); - - code_ += " bool KeyCompareLessThan(const std::optional<{{STRUCT_NAME}}<Iter>>& o) const {"; - if (is_string) { - // use operator< of flatbuffers::String - code_ += " return {{FIELD_NAME}}() < o->{{FIELD_NAME}}();"; - } else { - code_ += " return {{FIELD_NAME}}() < o->{{FIELD_NAME}}();"; - } - code_ += " }"; - - if (is_string) { - code_ += " int KeyCompareWithValue(const char *val) const {"; - code_ += " return strcmp({{FIELD_NAME}}()->str().c_str(), val);"; - code_ += " }"; - } else { - FLATBUFFERS_ASSERT(IsScalar(field.value.type.base_type)); - auto type = GenTypeBasic(field.value.type, false); - if (parser_.opts.scoped_enums && field.value.type.enum_def && - IsScalar(field.value.type.base_type)) { - type = GenTypeGet(field.value.type, " ", "const ", " *", true); - } - // Returns {field<val: -1, field==val: 0, field>val: +1}. - code_.SetValue("KEY_TYPE", type); - code_ += " int KeyCompareWithValue({{KEY_TYPE}} val) const {"; - code_ += - " return static_cast<int>({{FIELD_NAME}}() > val) - " - "static_cast<int>({{FIELD_NAME}}() < val);"; - code_ += " }"; - } - } - - - // Generate an accessor struct, builder structs & function for a table. - void GenTable(const StructDef &struct_def) { - // Generate an accessor struct, with methods of the form: - // type name() const { return GetField<type>(offset, defaultval); } - GenComment(struct_def.doc_comment); - - code_.SetValue("STRUCT_NAME", Name(struct_def)); - code_ += "template <typename Iter>"; - code_ += - "struct {{STRUCT_NAME}} FLATBUFFERS_FINAL_CLASS" - " : private yandex::maps::flatbuffers_iter::Table<Iter> {"; - - // Generate field id constants. - if (struct_def.fields.vec.size() > 0) { - // We need to add a trailing comma to all elements except the last one as - // older versions of gcc complain about this. - code_.SetValue("SEP", ""); - code_ += " enum {"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { - // Deprecated fields won't be accessible. - continue; - } - - code_.SetValue("OFFSET_NAME", GenFieldOffsetName(field)); - code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset)); - code_ += "{{SEP}} {{OFFSET_NAME}} = {{OFFSET_VALUE}}\\"; - code_.SetValue("SEP", ",\n"); - } - code_ += ""; - code_ += " };"; - } - - code_ += ""; - code_ += " using yandex::maps::flatbuffers_iter::Table<Iter>::Table;"; - - // Generate the accessors. - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { - // Deprecated fields won't be accessible. - continue; - } - - const bool is_struct = IsStruct(field.value.type); - const bool is_scalar = IsScalar(field.value.type.base_type); - code_.SetValue("FIELD_NAME", Name(field)); - - // Call a different accessor for pointers, that indirects. - std::string accessor = ""; - if (is_scalar) { - accessor = "this->template GetField<"; - } else if (is_struct) { - accessor = "this->template GetStruct<"; - } else { - accessor = "this->template GetPointer<"; - } - auto offset_str = GenFieldOffsetName(field); - auto offset_type = - GenTypeGet(field.value.type, "", "", "", false); - - auto call = accessor + offset_type + ">(" + offset_str; - // Default value as second arg for non-pointer types. - if (is_scalar) { call += ", " + GenDefaultConstant(field); } - call += ")"; - - GenComment(field.doc_comment, " "); - code_.SetValue("FIELD_TYPE", - GenTypeGet(field.value.type, " ", "std::optional<", "> ", true)); - code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, call)); - - code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {"; - code_ += " return {{FIELD_VALUE}};"; - code_ += " }"; - - // Generate a comparison function for this field if it is a key. - if (field.key) { - GenKeyFieldMethods(field); - } - } - - // Generate a verifier function that can check a buffer from an untrusted - // source will never cause reads outside the buffer. - code_ += " bool Verify(yandex::maps::flatbuffers_iter::Verifier<Iter> &verifier) const {"; - code_ += " return this->VerifyTableStart(verifier)\\"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { continue; } - GenVerifyCall(field, " &&\n "); - } - - code_ += " &&\n verifier.EndTable();"; - code_ += " }"; - - code_ += "};"; // End of table. - code_ += ""; - } - - // Set up the correct namespace. Only open a namespace if the existing one is - // different (closing/opening only what is necessary). - // - // The file must start and end with an empty (or null) namespace so that - // namespaces are properly opened and closed. - void SetNameSpace(const Namespace *ns) { - if (cur_name_space_ == ns) { return; } - - // Compute the size of the longest common namespace prefix. - // If cur_name_space is A::B::C::D and ns is A::B::E::F::G, - // the common prefix is A::B:: and we have old_size = 4, new_size = 5 - // and common_prefix_size = 2 - size_t old_size = cur_name_space_ ? cur_name_space_->components.size() : 0; - size_t new_size = ns ? ns->components.size() : 0; - - size_t common_prefix_size = 0; - while (common_prefix_size < old_size && common_prefix_size < new_size && - ns->components[common_prefix_size] == - cur_name_space_->components[common_prefix_size]) { - common_prefix_size++; - } - - // Close cur_name_space in reverse order to reach the common prefix. - // In the previous example, D then C are closed. - if (old_size > 0) - code_ += "} // namespace iter"; - for (size_t j = old_size; j > common_prefix_size; --j) { - code_ += "} // namespace " + cur_name_space_->components[j - 1]; - } - if (old_size != common_prefix_size) { code_ += ""; } - - // open namespace parts to reach the ns namespace - // in the previous example, E, then F, then G are opened - for (auto j = common_prefix_size; j != new_size; ++j) { - code_ += "namespace " + ns->components[j] + " {"; - } - if (new_size > 0) - code_ += "namespace iter {"; - if (new_size != common_prefix_size) { code_ += ""; } - - cur_name_space_ = ns; - } -}; - -} // namespace cpp_yandex_maps_iter - -bool GenerateCPPYandexMapsIter(const Parser &parser, const std::string &path, - const std::string &file_name) { - cpp_yandex_maps_iter::CppIterGenerator generator(parser, path, file_name); - return generator.generate(); -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_csharp.cpp b/contrib/libs/flatbuffers/src/idl_gen_csharp.cpp deleted file mode 100644 index 681ab6d642..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_csharp.cpp +++ /dev/null @@ -1,2100 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -#if defined(FLATBUFFERS_CPP98_STL) -# include <cctype> -#endif // defined(FLATBUFFERS_CPP98_STL) - -namespace flatbuffers { - -static TypedFloatConstantGenerator CSharpFloatGen("Double.", "Single.", "NaN", - "PositiveInfinity", - "NegativeInfinity"); -static CommentConfig comment_config = { - nullptr, - "///", - nullptr, -}; - -namespace csharp { -class CSharpGenerator : public BaseGenerator { - struct FieldArrayLength { - std::string name; - int length; - }; - - public: - CSharpGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", ".", "cs"), - cur_name_space_(nullptr) {} - - CSharpGenerator &operator=(const CSharpGenerator &); - - bool generate() { - std::string one_file_code; - cur_name_space_ = parser_.current_namespace_; - - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - std::string enumcode; - auto &enum_def = **it; - if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace; - GenEnum(enum_def, &enumcode, parser_.opts); - if (parser_.opts.one_file) { - one_file_code += enumcode; - } else { - if (!SaveType(enum_def.name, *enum_def.defined_namespace, enumcode, - false)) - return false; - } - } - - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - std::string declcode; - auto &struct_def = **it; - if (!parser_.opts.one_file) - cur_name_space_ = struct_def.defined_namespace; - GenStruct(struct_def, &declcode, parser_.opts); - if (parser_.opts.one_file) { - one_file_code += declcode; - } else { - if (!SaveType(struct_def.name, *struct_def.defined_namespace, declcode, - true)) - return false; - } - } - - if (parser_.opts.one_file) { - return SaveType(file_name_, *parser_.current_namespace_, one_file_code, - true); - } - return true; - } - - // Save out the generated code for a single class while adding - // declaration boilerplate. - bool SaveType(const std::string &defname, const Namespace &ns, - const std::string &classcode, bool needs_includes) const { - if (!classcode.length()) return true; - - std::string code = - "// <auto-generated>\n" - "// " + - std::string(FlatBuffersGeneratedWarning()) + - "\n" - "// </auto-generated>\n\n"; - - std::string namespace_name = FullNamespace(".", ns); - if (!namespace_name.empty()) { - code += "namespace " + namespace_name + "\n{\n\n"; - } - if (needs_includes) { - code += "using global::System;\n"; - code += "using global::System.Collections.Generic;\n"; - code += "using global::FlatBuffers;\n\n"; - } - code += classcode; - if (!namespace_name.empty()) { code += "\n}\n"; } - auto filename = NamespaceDir(ns) + defname + ".cs"; - return SaveFile(filename.c_str(), code, false); - } - - const Namespace *CurrentNameSpace() const { return cur_name_space_; } - - std::string GenTypeBasic(const Type &type, bool enableLangOverrides) const { - // clang-format off - static const char * const csharp_typename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, ...) \ - #NTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - - if (enableLangOverrides) { - if (IsEnum(type)) return WrapInNameSpace(*type.enum_def); - if (type.base_type == BASE_TYPE_STRUCT) { - return "Offset<" + WrapInNameSpace(*type.struct_def) + ">"; - } - } - - return csharp_typename[type.base_type]; - } - - inline std::string GenTypeBasic(const Type &type) const { - return GenTypeBasic(type, true); - } - - std::string GenTypePointer(const Type &type) const { - switch (type.base_type) { - case BASE_TYPE_STRING: return "string"; - case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); - case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def); - case BASE_TYPE_UNION: return "TTable"; - default: return "Table"; - } - } - - std::string GenTypeGet(const Type &type) const { - return IsScalar(type.base_type) - ? GenTypeBasic(type) - : (IsArray(type) ? GenTypeGet(type.VectorType()) - : GenTypePointer(type)); - } - - std::string GenOffsetType(const StructDef &struct_def) const { - return "Offset<" + WrapInNameSpace(struct_def) + ">"; - } - - std::string GenOffsetConstruct(const StructDef &struct_def, - const std::string &variable_name) const { - return "new Offset<" + WrapInNameSpace(struct_def) + ">(" + variable_name + - ")"; - } - - // Casts necessary to correctly read serialized data - std::string DestinationCast(const Type &type) const { - if (IsSeries(type)) { - return DestinationCast(type.VectorType()); - } else { - if (IsEnum(type)) return "(" + WrapInNameSpace(*type.enum_def) + ")"; - } - return ""; - } - - // Cast statements for mutator method parameters. - // In Java, parameters representing unsigned numbers need to be cast down to - // their respective type. For example, a long holding an unsigned int value - // would be cast down to int before being put onto the buffer. In C#, one cast - // directly cast an Enum to its underlying type, which is essential before - // putting it onto the buffer. - std::string SourceCast(const Type &type) const { - if (IsSeries(type)) { - return SourceCast(type.VectorType()); - } else { - if (IsEnum(type)) return "(" + GenTypeBasic(type, false) + ")"; - } - return ""; - } - - std::string SourceCastBasic(const Type &type) const { - return IsScalar(type.base_type) ? SourceCast(type) : ""; - } - - std::string GenEnumDefaultValue(const FieldDef &field) const { - auto &value = field.value; - FLATBUFFERS_ASSERT(value.type.enum_def); - auto &enum_def = *value.type.enum_def; - auto enum_val = enum_def.FindByValue(value.constant); - return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name) - : value.constant; - } - - std::string GenDefaultValue(const FieldDef &field, - bool enableLangOverrides) const { - // If it is an optional scalar field, the default is null - if (field.IsScalarOptional()) { return "null"; } - - auto &value = field.value; - if (enableLangOverrides) { - // handles both enum case and vector of enum case - if (value.type.enum_def != nullptr && - value.type.base_type != BASE_TYPE_UNION) { - return GenEnumDefaultValue(field); - } - } - - auto longSuffix = ""; - switch (value.type.base_type) { - case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true"; - case BASE_TYPE_ULONG: return value.constant; - case BASE_TYPE_UINT: - case BASE_TYPE_LONG: return value.constant + longSuffix; - default: - if (IsFloat(value.type.base_type)) - return CSharpFloatGen.GenFloatConstant(field); - else - return value.constant; - } - } - - std::string GenDefaultValue(const FieldDef &field) const { - return GenDefaultValue(field, true); - } - - std::string GenDefaultValueBasic(const FieldDef &field, - bool enableLangOverrides) const { - auto &value = field.value; - if (!IsScalar(value.type.base_type)) { - if (enableLangOverrides) { - switch (value.type.base_type) { - case BASE_TYPE_STRING: return "default(StringOffset)"; - case BASE_TYPE_STRUCT: - return "default(Offset<" + WrapInNameSpace(*value.type.struct_def) + - ">)"; - case BASE_TYPE_VECTOR: return "default(VectorOffset)"; - default: break; - } - } - return "0"; - } - return GenDefaultValue(field, enableLangOverrides); - } - - std::string GenDefaultValueBasic(const FieldDef &field) const { - return GenDefaultValueBasic(field, true); - } - - void GenEnum(EnumDef &enum_def, std::string *code_ptr, - const IDLOptions &opts) const { - std::string &code = *code_ptr; - if (enum_def.generated) return; - - // Generate enum definitions of the form: - // public static (final) int name = value; - // In Java, we use ints rather than the Enum feature, because we want them - // to map directly to how they're used in C/C++ and file formats. - // That, and Java Enums are expensive, and not universally liked. - GenComment(enum_def.doc_comment, code_ptr, &comment_config); - - if (opts.cs_gen_json_serializer && opts.generate_object_based_api) { - code += - "[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters." - "StringEnumConverter))]\n"; - } - // In C# this indicates enumeration values can be treated as bit flags. - if (enum_def.attributes.Lookup("bit_flags")) { - code += "[System.FlagsAttribute]\n"; - } - if (enum_def.attributes.Lookup("private")) { - code += "internal "; - } else { - code += "public "; - } - code += "enum " + enum_def.name; - code += " : " + GenTypeBasic(enum_def.underlying_type, false); - code += "\n{\n"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - GenComment(ev.doc_comment, code_ptr, &comment_config, " "); - code += " "; - code += ev.name + " = "; - code += enum_def.ToString(ev); - code += ",\n"; - } - // Close the class - code += "};\n\n"; - - if (opts.generate_object_based_api) { - GenEnum_ObjectAPI(enum_def, code_ptr, opts); - } - } - - bool HasUnionStringValue(const EnumDef &enum_def) const { - if (!enum_def.is_union) return false; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &val = **it; - if (IsString(val.union_type)) { return true; } - } - return false; - } - - // Returns the function name that is able to read a value of the given type. - std::string GenGetter(const Type &type) const { - switch (type.base_type) { - case BASE_TYPE_STRING: return "__p.__string"; - case BASE_TYPE_STRUCT: return "__p.__struct"; - case BASE_TYPE_UNION: return "__p.__union"; - case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); - case BASE_TYPE_ARRAY: return GenGetter(type.VectorType()); - default: { - std::string getter = "__p.bb.Get"; - if (type.base_type == BASE_TYPE_BOOL) { - getter = "0!=" + getter; - } else if (GenTypeBasic(type, false) != "byte") { - getter += MakeCamel(GenTypeBasic(type, false)); - } - return getter; - } - } - } - - // Returns the function name that is able to read a value of the given type. - std::string GenGetterForLookupByKey(flatbuffers::FieldDef *key_field, - const std::string &data_buffer, - const char *num = nullptr) const { - auto type = key_field->value.type; - auto dest_mask = ""; - auto dest_cast = DestinationCast(type); - auto getter = data_buffer + ".Get"; - if (GenTypeBasic(type, false) != "byte") { - getter += MakeCamel(GenTypeBasic(type, false)); - } - getter = dest_cast + getter + "(" + GenOffsetGetter(key_field, num) + ")" + - dest_mask; - return getter; - } - - // Direct mutation is only allowed for scalar fields. - // Hence a setter method will only be generated for such fields. - std::string GenSetter(const Type &type) const { - if (IsScalar(type.base_type)) { - std::string setter = "__p.bb.Put"; - if (GenTypeBasic(type, false) != "byte" && - type.base_type != BASE_TYPE_BOOL) { - setter += MakeCamel(GenTypeBasic(type, false)); - } - return setter; - } else { - return ""; - } - } - - // Returns the method name for use with add/put calls. - std::string GenMethod(const Type &type) const { - return IsScalar(type.base_type) ? MakeCamel(GenTypeBasic(type, false)) - : (IsStruct(type) ? "Struct" : "Offset"); - } - - // Recursively generate arguments for a constructor, to deal with nested - // structs. - void GenStructArgs(const StructDef &struct_def, std::string *code_ptr, - const char *nameprefix, size_t array_count = 0) const { - std::string &code = *code_ptr; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - const auto &field_type = field.value.type; - const auto array_field = IsArray(field_type); - const auto &type = array_field ? field_type.VectorType() : field_type; - const auto array_cnt = array_field ? (array_count + 1) : array_count; - if (IsStruct(type)) { - // Generate arguments for a struct inside a struct. To ensure names - // don't clash, and to make it obvious these arguments are constructing - // a nested struct, prefix the name with the field name. - GenStructArgs(*field_type.struct_def, code_ptr, - (nameprefix + (field.name + "_")).c_str(), array_cnt); - } else { - code += ", "; - code += GenTypeBasic(type); - if (field.IsScalarOptional()) { code += "?"; } - if (array_cnt > 0) { - code += "["; - for (size_t i = 1; i < array_cnt; i++) code += ","; - code += "]"; - } - code += " "; - code += nameprefix; - code += MakeCamel(field.name, true); - } - } - } - - // Recusively generate struct construction statements of the form: - // builder.putType(name); - // and insert manual padding. - void GenStructBody(const StructDef &struct_def, std::string *code_ptr, - const char *nameprefix, size_t index = 0, - bool in_array = false) const { - std::string &code = *code_ptr; - std::string indent((index + 1) * 2, ' '); - code += indent + " builder.Prep("; - code += NumToString(struct_def.minalign) + ", "; - code += NumToString(struct_def.bytesize) + ");\n"; - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - const auto &field_type = field.value.type; - if (field.padding) { - code += indent + " builder.Pad("; - code += NumToString(field.padding) + ");\n"; - } - if (IsStruct(field_type)) { - GenStructBody(*field_type.struct_def, code_ptr, - (nameprefix + (field.name + "_")).c_str(), index, - in_array); - } else { - const auto &type = - IsArray(field_type) ? field_type.VectorType() : field_type; - const auto index_var = "_idx" + NumToString(index); - if (IsArray(field_type)) { - code += indent + " for (int " + index_var + " = "; - code += NumToString(field_type.fixed_length); - code += "; " + index_var + " > 0; " + index_var + "--) {\n"; - in_array = true; - } - if (IsStruct(type)) { - GenStructBody(*field_type.struct_def, code_ptr, - (nameprefix + (field.name + "_")).c_str(), index + 1, - in_array); - } else { - code += IsArray(field_type) ? " " : ""; - code += indent + " builder.Put"; - code += GenMethod(type) + "("; - code += SourceCast(type); - auto argname = nameprefix + MakeCamel(field.name, true); - code += argname; - size_t array_cnt = index + (IsArray(field_type) ? 1 : 0); - if (array_cnt > 0) { - code += "["; - for (size_t i = 0; in_array && i < array_cnt; i++) { - code += "_idx" + NumToString(i) + "-1"; - if (i != (array_cnt - 1)) code += ","; - } - code += "]"; - } - code += ");\n"; - } - if (IsArray(field_type)) { code += indent + " }\n"; } - } - } - } - std::string GenOffsetGetter(flatbuffers::FieldDef *key_field, - const char *num = nullptr) const { - std::string key_offset = - "Table.__offset(" + NumToString(key_field->value.offset) + ", "; - if (num) { - key_offset += num; - key_offset += ".Value, builder.DataBuffer)"; - } else { - key_offset += "bb.Length"; - key_offset += " - tableOffset, bb)"; - } - return key_offset; - } - - std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) const { - std::string key_getter = " "; - key_getter += "int tableOffset = Table."; - key_getter += "__indirect(vectorLocation + 4 * (start + middle)"; - key_getter += ", bb);\n "; - if (IsString(key_field->value.type)) { - key_getter += "int comp = Table."; - key_getter += "CompareStrings("; - key_getter += GenOffsetGetter(key_field); - key_getter += ", byteKey, bb);\n"; - } else { - auto get_val = GenGetterForLookupByKey(key_field, "bb"); - key_getter += "int comp = " + get_val + ".CompareTo(key);\n"; - } - return key_getter; - } - - std::string GenKeyGetter(flatbuffers::FieldDef *key_field) const { - std::string key_getter = ""; - auto data_buffer = "builder.DataBuffer"; - if (IsString(key_field->value.type)) { - key_getter += "Table.CompareStrings("; - key_getter += GenOffsetGetter(key_field, "o1") + ", "; - key_getter += GenOffsetGetter(key_field, "o2") + ", " + data_buffer + ")"; - } else { - auto field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o1"); - key_getter += field_getter; - field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o2"); - key_getter += ".CompareTo(" + field_getter + ")"; - } - return key_getter; - } - - void GenStruct(StructDef &struct_def, std::string *code_ptr, - const IDLOptions &opts) const { - if (struct_def.generated) return; - std::string &code = *code_ptr; - - // Generate a struct accessor class, with methods of the form: - // public type name() { return bb.getType(i + offset); } - // or for tables of the form: - // public type name() { - // int o = __offset(offset); return o != 0 ? bb.getType(o + i) : default; - // } - GenComment(struct_def.doc_comment, code_ptr, &comment_config); - if (struct_def.attributes.Lookup("private")) { - code += "internal "; - } else { - code += "public "; - } - if (struct_def.attributes.Lookup("csharp_partial")) { - // generate a partial class for this C# struct/table - code += "partial "; - } - code += "struct " + struct_def.name; - code += " : IFlatbufferObject"; - code += "\n{\n"; - code += " private "; - code += struct_def.fixed ? "Struct" : "Table"; - code += " __p;\n"; - - code += " public ByteBuffer ByteBuffer { get { return __p.bb; } }\n"; - - if (!struct_def.fixed) { - // Generate verson check method. - // Force compile time error if not using the same version runtime. - code += " public static void ValidateVersion() {"; - code += " FlatBufferConstants."; - code += "FLATBUFFERS_2_0_0(); "; - code += "}\n"; - - // Generate a special accessor for the table that when used as the root - // of a FlatBuffer - std::string method_name = "GetRootAs" + struct_def.name; - std::string method_signature = - " public static " + struct_def.name + " " + method_name; - - // create convenience method that doesn't require an existing object - code += method_signature + "(ByteBuffer _bb) "; - code += "{ return " + method_name + "(_bb, new " + struct_def.name + - "()); }\n"; - - // create method that allows object reuse - code += - method_signature + "(ByteBuffer _bb, " + struct_def.name + " obj) { "; - code += "return (obj.__assign(_bb.GetInt(_bb.Position"; - code += ") + _bb.Position"; - code += ", _bb)); }\n"; - if (parser_.root_struct_def_ == &struct_def) { - if (parser_.file_identifier_.length()) { - // Check if a buffer has the identifier. - code += " public static "; - code += "bool " + struct_def.name; - code += "BufferHasIdentifier(ByteBuffer _bb) { return "; - code += "Table.__has_identifier(_bb, \""; - code += parser_.file_identifier_; - code += "\"); }\n"; - } - } - } - // Generate the __init method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - code += " public void __init(int _i, ByteBuffer _bb) "; - code += "{ "; - code += "__p = new "; - code += struct_def.fixed ? "Struct" : "Table"; - code += "(_i, _bb); "; - code += "}\n"; - code += - " public " + struct_def.name + " __assign(int _i, ByteBuffer _bb) "; - code += "{ __init(_i, _bb); return this; }\n\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - GenComment(field.doc_comment, code_ptr, &comment_config, " "); - std::string type_name = GenTypeGet(field.value.type); - std::string type_name_dest = GenTypeGet(field.value.type); - std::string conditional_cast = ""; - std::string optional = ""; - if (!struct_def.fixed && - (field.value.type.base_type == BASE_TYPE_STRUCT || - field.value.type.base_type == BASE_TYPE_UNION || - (IsVector(field.value.type) && - (field.value.type.element == BASE_TYPE_STRUCT || - field.value.type.element == BASE_TYPE_UNION)))) { - optional = "?"; - conditional_cast = "(" + type_name_dest + optional + ")"; - } - if (field.IsScalarOptional()) { optional = "?"; } - std::string dest_mask = ""; - std::string dest_cast = DestinationCast(field.value.type); - std::string src_cast = SourceCast(field.value.type); - std::string field_name_camel = MakeCamel(field.name, true); - std::string method_start = - " public " + type_name_dest + optional + " " + field_name_camel; - std::string obj = "(new " + type_name + "())"; - - // Most field accessors need to retrieve and test the field offset first, - // this is the prefix code for that: - auto offset_prefix = - IsArray(field.value.type) - ? " { return " - : (" { int o = __p.__offset(" + NumToString(field.value.offset) + - "); return o != 0 ? "); - // Generate the accessors that don't do object reuse. - if (field.value.type.base_type == BASE_TYPE_STRUCT) { - } else if (IsVector(field.value.type) && - field.value.type.element == BASE_TYPE_STRUCT) { - } else if (field.value.type.base_type == BASE_TYPE_UNION || - (IsVector(field.value.type) && - field.value.type.VectorType().base_type == BASE_TYPE_UNION)) { - method_start += "<TTable>"; - type_name = type_name_dest; - } - std::string getter = dest_cast + GenGetter(field.value.type); - code += method_start; - std::string default_cast = ""; - // only create default casts for c# scalars or vectors of scalars - if ((IsScalar(field.value.type.base_type) || - (IsVector(field.value.type) && - IsScalar(field.value.type.element)))) { - // For scalars, default value will be returned by GetDefaultValue(). - // If the scalar is an enum, GetDefaultValue() returns an actual c# enum - // that doesn't need to be casted. However, default values for enum - // elements of vectors are integer literals ("0") and are still casted - // for clarity. - // If the scalar is optional and enum, we still need the cast. - if ((field.value.type.enum_def == nullptr || - IsVector(field.value.type)) || - (IsEnum(field.value.type) && field.IsScalarOptional())) { - default_cast = "(" + type_name_dest + optional + ")"; - } - } - std::string member_suffix = "; "; - if (IsScalar(field.value.type.base_type)) { - code += " { get"; - member_suffix += "} "; - if (struct_def.fixed) { - code += " { return " + getter; - code += "(__p.bb_pos + "; - code += NumToString(field.value.offset) + ")"; - code += dest_mask; - } else { - code += offset_prefix + getter; - code += "(o + __p.bb_pos)" + dest_mask; - code += " : " + default_cast; - code += GenDefaultValue(field); - } - } else { - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: - code += " { get"; - member_suffix += "} "; - if (struct_def.fixed) { - code += " { return " + obj + ".__assign(" + "__p."; - code += "bb_pos + " + NumToString(field.value.offset) + ", "; - code += "__p.bb)"; - } else { - code += offset_prefix + conditional_cast; - code += obj + ".__assign("; - code += field.value.type.struct_def->fixed - ? "o + __p.bb_pos" - : "__p.__indirect(o + __p.bb_pos)"; - code += ", __p.bb) : null"; - } - break; - case BASE_TYPE_STRING: - code += " { get"; - member_suffix += "} "; - code += offset_prefix + getter + "(o + " + "__p."; - code += "bb_pos) : null"; - break; - case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - if (vectortype.base_type == BASE_TYPE_UNION) { - conditional_cast = "(TTable?)"; - getter += "<TTable>"; - } - code += "("; - if (vectortype.base_type == BASE_TYPE_STRUCT) { - getter = obj + ".__assign"; - } else if (vectortype.base_type == BASE_TYPE_UNION) { - } - code += "int j)"; - const auto body = offset_prefix + conditional_cast + getter + "("; - if (vectortype.base_type == BASE_TYPE_UNION) { - code += " where TTable : struct, IFlatbufferObject" + body; - } else { - code += body; - } - std::string index = "__p."; - if (IsArray(field.value.type)) { - index += "bb_pos + " + NumToString(field.value.offset) + " + "; - } else { - index += "__vector(o) + "; - } - index += "j * " + NumToString(InlineSize(vectortype)); - if (vectortype.base_type == BASE_TYPE_STRUCT) { - code += vectortype.struct_def->fixed - ? index - : "__p.__indirect(" + index + ")"; - code += ", __p.bb"; - } else { - code += index; - } - code += ")" + dest_mask; - if (!IsArray(field.value.type)) { - code += " : "; - code += - field.value.type.element == BASE_TYPE_BOOL - ? "false" - : (IsScalar(field.value.type.element) ? default_cast + "0" - : "null"); - } - if (vectortype.base_type == BASE_TYPE_UNION && - HasUnionStringValue(*vectortype.enum_def)) { - code += member_suffix; - code += "}\n"; - code += " public string " + MakeCamel(field.name, true) + - "AsString(int j)"; - code += offset_prefix + GenGetter(Type(BASE_TYPE_STRING)); - code += "(" + index + ") : null"; - } - break; - } - case BASE_TYPE_UNION: - code += "() where TTable : struct, IFlatbufferObject"; - code += offset_prefix + "(TTable?)" + getter; - code += "<TTable>(o + __p.bb_pos) : null"; - if (HasUnionStringValue(*field.value.type.enum_def)) { - code += member_suffix; - code += "}\n"; - code += " public string " + MakeCamel(field.name, true) + - "AsString()"; - code += offset_prefix + GenGetter(Type(BASE_TYPE_STRING)); - code += "(o + __p.bb_pos) : null"; - } - // As<> accesors for Unions - // Loop through all the possible union types and generate an As - // accessor that casts to the correct type. - for (auto uit = field.value.type.enum_def->Vals().begin(); - uit != field.value.type.enum_def->Vals().end(); ++uit) { - auto val = *uit; - if (val->union_type.base_type == BASE_TYPE_NONE) { continue; } - auto union_field_type_name = GenTypeGet(val->union_type); - code += member_suffix + "}\n"; - if (val->union_type.base_type == BASE_TYPE_STRUCT && - val->union_type.struct_def->attributes.Lookup("private")) { - code += " internal "; - } else { - code += " public "; - } - code += union_field_type_name + " "; - code += field_name_camel + "As" + val->name + "() { return "; - code += field_name_camel; - if (IsString(val->union_type)) { - code += "AsString()"; - } else { - code += "<" + union_field_type_name + ">().Value"; - } - } - break; - default: FLATBUFFERS_ASSERT(0); - } - } - code += member_suffix; - code += "}\n"; - if (IsVector(field.value.type)) { - code += " public int " + MakeCamel(field.name, true); - code += "Length"; - code += " { get"; - code += offset_prefix; - code += "__p.__vector_len(o) : 0; "; - code += "} "; - code += "}\n"; - // See if we should generate a by-key accessor. - if (field.value.type.element == BASE_TYPE_STRUCT && - !field.value.type.struct_def->fixed) { - auto &sd = *field.value.type.struct_def; - auto &fields = sd.fields.vec; - for (auto kit = fields.begin(); kit != fields.end(); ++kit) { - auto &key_field = **kit; - if (key_field.key) { - auto qualified_name = WrapInNameSpace(sd); - code += " public " + qualified_name + "? "; - code += MakeCamel(field.name, true) + "ByKey("; - code += GenTypeGet(key_field.value.type) + " key)"; - code += offset_prefix; - code += qualified_name + ".__lookup_by_key("; - code += "__p.__vector(o), key, "; - code += "__p.bb) : null; "; - code += "}\n"; - break; - } - } - } - } - // Generate a ByteBuffer accessor for strings & vectors of scalars. - if ((IsVector(field.value.type) && - IsScalar(field.value.type.VectorType().base_type)) || - IsString(field.value.type)) { - code += "#if ENABLE_SPAN_T\n"; - code += " public Span<" + GenTypeBasic(field.value.type.VectorType()) + - "> Get"; - code += MakeCamel(field.name, true); - code += "Bytes() { return "; - code += "__p.__vector_as_span<" + - GenTypeBasic(field.value.type.VectorType()) + ">("; - code += NumToString(field.value.offset); - code += - ", " + NumToString(SizeOf(field.value.type.VectorType().base_type)); - code += "); }\n"; - code += "#else\n"; - code += " public ArraySegment<byte>? Get"; - code += MakeCamel(field.name, true); - code += "Bytes() { return "; - code += "__p.__vector_as_arraysegment("; - code += NumToString(field.value.offset); - code += "); }\n"; - code += "#endif\n"; - - // For direct blockcopying the data into a typed array - code += " public "; - code += GenTypeBasic(field.value.type.VectorType()); - code += "[] Get"; - code += MakeCamel(field.name, true); - code += "Array() { "; - if (IsEnum(field.value.type.VectorType())) { - // Since __vector_as_array does not work for enum types, - // fill array using an explicit loop. - code += "int o = __p.__offset("; - code += NumToString(field.value.offset); - code += "); if (o == 0) return null; int p = "; - code += "__p.__vector(o); int l = "; - code += "__p.__vector_len(o); "; - code += GenTypeBasic(field.value.type.VectorType()); - code += "[] a = new "; - code += GenTypeBasic(field.value.type.VectorType()); - code += "[l]; for (int i = 0; i < l; i++) { a[i] = " + getter; - code += "(p + i * "; - code += NumToString(InlineSize(field.value.type.VectorType())); - code += "); } return a;"; - } else { - code += "return "; - code += "__p.__vector_as_array<"; - code += GenTypeBasic(field.value.type.VectorType()); - code += ">("; - code += NumToString(field.value.offset); - code += ");"; - } - code += " }\n"; - } - // generate object accessors if is nested_flatbuffer - if (field.nested_flatbuffer) { - auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer); - auto nested_method_name = - MakeCamel(field.name, true) + "As" + field.nested_flatbuffer->name; - auto get_nested_method_name = nested_method_name; - get_nested_method_name = "Get" + nested_method_name; - conditional_cast = "(" + nested_type_name + "?)"; - obj = "(new " + nested_type_name + "())"; - code += " public " + nested_type_name + "? "; - code += get_nested_method_name + "("; - code += ") { int o = __p.__offset("; - code += NumToString(field.value.offset) + "); "; - code += "return o != 0 ? " + conditional_cast + obj + ".__assign("; - code += "__p."; - code += "__indirect(__p.__vector(o)), "; - code += "__p.bb) : null; }\n"; - } - // Generate mutators for scalar fields or vectors of scalars. - if (parser_.opts.mutable_buffer) { - auto is_series = (IsSeries(field.value.type)); - const auto &underlying_type = - is_series ? field.value.type.VectorType() : field.value.type; - // Boolean parameters have to be explicitly converted to byte - // representation. - auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL - ? "(byte)(" + field.name + " ? 1 : 0)" - : field.name; - auto mutator_prefix = MakeCamel("mutate", true); - // A vector mutator also needs the index of the vector element it should - // mutate. - auto mutator_params = (is_series ? "(int j, " : "(") + - GenTypeGet(underlying_type) + " " + field.name + - ") { "; - auto setter_index = - is_series - ? "__p." + - (IsArray(field.value.type) - ? "bb_pos + " + NumToString(field.value.offset) - : "__vector(o)") + - +" + j * " + NumToString(InlineSize(underlying_type)) - : (struct_def.fixed - ? "__p.bb_pos + " + NumToString(field.value.offset) - : "o + __p.bb_pos"); - if (IsScalar(underlying_type.base_type) && !IsUnion(field.value.type)) { - code += " public "; - code += struct_def.fixed ? "void " : "bool "; - code += mutator_prefix + MakeCamel(field.name, true); - code += mutator_params; - if (struct_def.fixed) { - code += GenSetter(underlying_type) + "(" + setter_index + ", "; - code += src_cast + setter_parameter + "); }\n"; - } else { - code += "int o = __p.__offset("; - code += NumToString(field.value.offset) + ");"; - code += " if (o != 0) { " + GenSetter(underlying_type); - code += "(" + setter_index + ", " + src_cast + setter_parameter + - "); return true; } else { return false; } }\n"; - } - } - } - if (parser_.opts.java_primitive_has_method && - IsScalar(field.value.type.base_type) && !struct_def.fixed) { - auto vt_offset_constant = " public static final int VT_" + - MakeScreamingCamel(field.name) + " = " + - NumToString(field.value.offset) + ";"; - - code += vt_offset_constant; - code += "\n"; - } - } - code += "\n"; - auto struct_has_create = false; - std::set<flatbuffers::FieldDef *> field_has_create_set; - flatbuffers::FieldDef *key_field = nullptr; - if (struct_def.fixed) { - struct_has_create = true; - // create a struct constructor function - code += " public static " + GenOffsetType(struct_def) + " "; - code += "Create"; - code += struct_def.name + "(FlatBufferBuilder builder"; - GenStructArgs(struct_def, code_ptr, ""); - code += ") {\n"; - GenStructBody(struct_def, code_ptr, ""); - code += " return "; - code += GenOffsetConstruct(struct_def, "builder.Offset"); - code += ";\n }\n"; - } else { - // Generate a method that creates a table in one go. This is only possible - // when the table has no struct fields, since those have to be created - // inline, and there's no way to do so in Java. - bool has_no_struct_fields = true; - int num_fields = 0; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (IsStruct(field.value.type)) { - has_no_struct_fields = false; - } else { - num_fields++; - } - } - // JVM specifications restrict default constructor params to be < 255. - // Longs and doubles take up 2 units, so we set the limit to be < 127. - if ((has_no_struct_fields || opts.generate_object_based_api) && - num_fields && num_fields < 127) { - struct_has_create = true; - // Generate a table constructor of the form: - // public static int createName(FlatBufferBuilder builder, args...) - code += " public static " + GenOffsetType(struct_def) + " "; - code += "Create" + struct_def.name; - code += "(FlatBufferBuilder builder"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - code += ",\n "; - if (IsStruct(field.value.type) && opts.generate_object_based_api) { - code += WrapInNameSpace( - field.value.type.struct_def->defined_namespace, - GenTypeName_ObjectAPI(field.value.type.struct_def->name, opts)); - code += " "; - code += field.name; - code += " = null"; - } else { - code += GenTypeBasic(field.value.type); - if (field.IsScalarOptional()) { code += "?"; } - code += " "; - code += field.name; - if (!IsScalar(field.value.type.base_type)) code += "Offset"; - - code += " = "; - code += GenDefaultValueBasic(field); - } - } - code += ") {\n builder."; - code += "StartTable("; - code += NumToString(struct_def.fields.vec.size()) + ");\n"; - for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1; - size; size /= 2) { - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - if (!field.deprecated && - (!struct_def.sortbysize || - size == SizeOf(field.value.type.base_type))) { - code += " " + struct_def.name + "."; - code += "Add"; - code += MakeCamel(field.name) + "(builder, "; - if (IsStruct(field.value.type) && - opts.generate_object_based_api) { - code += GenTypePointer(field.value.type) + ".Pack(builder, " + - field.name + ")"; - } else { - code += field.name; - if (!IsScalar(field.value.type.base_type)) code += "Offset"; - } - - code += ");\n"; - } - } - } - code += " return " + struct_def.name + "."; - code += "End" + struct_def.name; - code += "(builder);\n }\n\n"; - } - // Generate a set of static methods that allow table construction, - // of the form: - // public static void addName(FlatBufferBuilder builder, short name) - // { builder.addShort(id, name, default); } - // Unlike the Create function, these always work. - code += " public static void Start"; - code += struct_def.name; - code += "(FlatBufferBuilder builder) { builder."; - code += "StartTable("; - code += NumToString(struct_def.fields.vec.size()) + "); }\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (field.key) key_field = &field; - code += " public static void Add"; - code += MakeCamel(field.name); - code += "(FlatBufferBuilder builder, "; - code += GenTypeBasic(field.value.type); - auto argname = MakeCamel(field.name, false); - if (!IsScalar(field.value.type.base_type)) argname += "Offset"; - if (field.IsScalarOptional()) { code += "?"; } - code += " " + argname + ") { builder.Add"; - code += GenMethod(field.value.type) + "("; - code += NumToString(it - struct_def.fields.vec.begin()) + ", "; - code += SourceCastBasic(field.value.type); - code += argname; - if (!IsScalar(field.value.type.base_type) && - field.value.type.base_type != BASE_TYPE_UNION) { - code += ".Value"; - } - if (!field.IsScalarOptional()) { - // When the scalar is optional, use the builder method that doesn't - // supply a default value. Otherwise, we to continue to use the - // default value method. - code += ", "; - code += GenDefaultValue(field, false); - } - code += "); }\n"; - if (IsVector(field.value.type)) { - auto vector_type = field.value.type.VectorType(); - auto alignment = InlineAlignment(vector_type); - auto elem_size = InlineSize(vector_type); - if (!IsStruct(vector_type)) { - field_has_create_set.insert(&field); - code += " public static VectorOffset "; - code += "Create"; - code += MakeCamel(field.name); - code += "Vector(FlatBufferBuilder builder, "; - code += GenTypeBasic(vector_type) + "[] data) "; - code += "{ builder.StartVector("; - code += NumToString(elem_size); - code += ", data.Length, "; - code += NumToString(alignment); - code += "); for (int i = data."; - code += "Length - 1; i >= 0; i--) builder."; - code += "Add"; - code += GenMethod(vector_type); - code += "("; - code += SourceCastBasic(vector_type); - code += "data[i]"; - if (vector_type.base_type == BASE_TYPE_STRUCT || - IsString(vector_type)) - code += ".Value"; - code += "); return "; - code += "builder.EndVector(); }\n"; - - code += " public static VectorOffset "; - code += "Create"; - code += MakeCamel(field.name); - code += "VectorBlock(FlatBufferBuilder builder, "; - code += GenTypeBasic(vector_type) + "[] data) "; - code += "{ builder.StartVector("; - code += NumToString(elem_size); - code += ", data.Length, "; - code += NumToString(alignment); - code += "); builder.Add(data); return builder.EndVector(); }\n"; - } - // Generate a method to start a vector, data to be added manually - // after. - code += " public static void Start"; - code += MakeCamel(field.name); - code += "Vector(FlatBufferBuilder builder, int numElems) "; - code += "{ builder.StartVector("; - code += NumToString(elem_size); - code += ", numElems, " + NumToString(alignment); - code += "); }\n"; - } - } - code += " public static " + GenOffsetType(struct_def) + " "; - code += "End" + struct_def.name; - code += "(FlatBufferBuilder builder) {\n int o = builder."; - code += "EndTable();\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (!field.deprecated && field.IsRequired()) { - code += " builder.Required(o, "; - code += NumToString(field.value.offset); - code += "); // " + field.name + "\n"; - } - } - code += " return " + GenOffsetConstruct(struct_def, "o") + ";\n }\n"; - if (parser_.root_struct_def_ == &struct_def) { - std::string size_prefix[] = { "", "SizePrefixed" }; - for (int i = 0; i < 2; ++i) { - code += " public static void "; - code += "Finish" + size_prefix[i] + struct_def.name; - code += - "Buffer(FlatBufferBuilder builder, " + GenOffsetType(struct_def); - code += " offset) {"; - code += " builder.Finish" + size_prefix[i] + "(offset"; - code += ".Value"; - - if (parser_.file_identifier_.length()) - code += ", \"" + parser_.file_identifier_ + "\""; - code += "); }\n"; - } - } - } - // Only generate key compare function for table, - // because `key_field` is not set for struct - if (struct_def.has_key && !struct_def.fixed) { - FLATBUFFERS_ASSERT(key_field); - code += "\n public static VectorOffset "; - code += "CreateSortedVectorOf" + struct_def.name; - code += "(FlatBufferBuilder builder, "; - code += "Offset<" + struct_def.name + ">"; - code += "[] offsets) {\n"; - code += " Array.Sort(offsets, (Offset<" + struct_def.name + - "> o1, Offset<" + struct_def.name + "> o2) => " + - GenKeyGetter(key_field); - code += ");\n"; - code += " return builder.CreateVectorOfTables(offsets);\n }\n"; - - code += "\n public static " + struct_def.name + "?"; - code += " __lookup_by_key("; - code += "int vectorLocation, "; - code += GenTypeGet(key_field->value.type); - code += " key, ByteBuffer bb) {\n"; - if (IsString(key_field->value.type)) { - code += " byte[] byteKey = "; - code += "System.Text.Encoding.UTF8.GetBytes(key);\n"; - } - code += " int span = "; - code += "bb.GetInt(vectorLocation - 4);\n"; - code += " int start = 0;\n"; - code += " while (span != 0) {\n"; - code += " int middle = span / 2;\n"; - code += GenLookupKeyGetter(key_field); - code += " if (comp > 0) {\n"; - code += " span = middle;\n"; - code += " } else if (comp < 0) {\n"; - code += " middle++;\n"; - code += " start += middle;\n"; - code += " span -= middle;\n"; - code += " } else {\n"; - code += " return "; - code += "new " + struct_def.name + "()"; - code += ".__assign(tableOffset, bb);\n"; - code += " }\n }\n"; - code += " return null;\n"; - code += " }\n"; - } - - if (opts.generate_object_based_api) { - GenPackUnPack_ObjectAPI(struct_def, code_ptr, opts, struct_has_create, - field_has_create_set); - } - code += "};\n\n"; - - if (opts.generate_object_based_api) { - GenStruct_ObjectAPI(struct_def, code_ptr, opts); - } - } - - void GenVectorAccessObject(StructDef &struct_def, - std::string *code_ptr) const { - auto &code = *code_ptr; - // Generate a vector of structs accessor class. - code += "\n"; - code += " "; - if (!struct_def.attributes.Lookup("private")) code += "public "; - code += "static struct Vector : BaseVector\n{\n"; - - // Generate the __assign method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - std::string method_indent = " "; - code += method_indent + "public Vector "; - code += "__assign(int _vector, int _element_size, ByteBuffer _bb) { "; - code += "__reset(_vector, _element_size, _bb); return this; }\n\n"; - - auto type_name = struct_def.name; - auto method_start = method_indent + "public " + type_name + " Get"; - // Generate the accessors that don't do object reuse. - code += method_start + "(int j) { return Get"; - code += "(new " + type_name + "(), j); }\n"; - code += method_start + "(" + type_name + " obj, int j) { "; - code += " return obj.__assign("; - code += struct_def.fixed ? "__p.__element(j)" - : "__p.__indirect(__p.__element(j), bb)"; - code += ", __p.bb); }\n"; - // See if we should generate a by-key accessor. - if (!struct_def.fixed) { - auto &fields = struct_def.fields.vec; - for (auto kit = fields.begin(); kit != fields.end(); ++kit) { - auto &key_field = **kit; - if (key_field.key) { - auto nullable_annotation = - parser_.opts.gen_nullable ? "@Nullable " : ""; - code += method_indent + nullable_annotation; - code += "public " + type_name + "? "; - code += "GetByKey("; - code += GenTypeGet(key_field.value.type) + " key) { "; - code += " return __lookup_by_key(null, "; - code += "__p.__vector(), key, "; - code += "__p.bb); "; - code += "}\n"; - code += method_indent + nullable_annotation; - code += "public " + type_name + "?" + " "; - code += "GetByKey("; - code += type_name + "? obj, "; - code += GenTypeGet(key_field.value.type) + " key) { "; - code += " return __lookup_by_key(obj, "; - code += "__p.__vector(), key, "; - code += "__p.bb); "; - code += "}\n"; - break; - } - } - } - code += " }\n"; - } - - void GenEnum_ObjectAPI(EnumDef &enum_def, std::string *code_ptr, - const IDLOptions &opts) const { - auto &code = *code_ptr; - if (enum_def.generated) return; - if (!enum_def.is_union) return; - if (enum_def.attributes.Lookup("private")) { - code += "internal "; - } else { - code += "public "; - } - auto union_name = enum_def.name + "Union"; - code += "class " + union_name + " {\n"; - // Type - code += " public " + enum_def.name + " Type { get; set; }\n"; - // Value - code += " public object Value { get; set; }\n"; - code += "\n"; - // Constructor - code += " public " + union_name + "() {\n"; - code += " this.Type = " + enum_def.name + "." + - enum_def.Vals()[0]->name + ";\n"; - code += " this.Value = null;\n"; - code += " }\n\n"; - // As<T> - code += " public T As<T>() where T : class { return this.Value as T; }\n"; - // As - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - if (ev.union_type.base_type == BASE_TYPE_NONE) continue; - auto type_name = GenTypeGet_ObjectAPI(ev.union_type, opts); - if (ev.union_type.base_type == BASE_TYPE_STRUCT && - ev.union_type.struct_def->attributes.Lookup("private")) { - code += " internal "; - } else { - code += " public "; - } - code += type_name + " As" + ev.name + "() { return this.As<" + type_name + - ">(); }\n"; - } - code += "\n"; - // Pack() - code += " public static int Pack(FlatBuffers.FlatBufferBuilder builder, " + - union_name + " _o) {\n"; - code += " switch (_o.Type) {\n"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - if (ev.union_type.base_type == BASE_TYPE_NONE) { - code += " default: return 0;\n"; - } else { - code += " case " + enum_def.name + "." + ev.name + ": return "; - if (IsString(ev.union_type)) { - code += "builder.CreateString(_o.As" + ev.name + "()).Value;\n"; - } else { - code += GenTypeGet(ev.union_type) + ".Pack(builder, _o.As" + ev.name + - "()).Value;\n"; - } - } - } - code += " }\n"; - code += " }\n"; - code += "}\n\n"; - // JsonConverter - if (opts.cs_gen_json_serializer) { - if (enum_def.attributes.Lookup("private")) { - code += "internal "; - } else { - code += "public "; - } - code += "class " + union_name + - "_JsonConverter : Newtonsoft.Json.JsonConverter {\n"; - code += " public override bool CanConvert(System.Type objectType) {\n"; - code += " return objectType == typeof(" + union_name + - ") || objectType == typeof(System.Collections.Generic.List<" + - union_name + ">);\n"; - code += " }\n"; - code += - " public override void WriteJson(Newtonsoft.Json.JsonWriter writer, " - "object value, " - "Newtonsoft.Json.JsonSerializer serializer) {\n"; - code += " var _olist = value as System.Collections.Generic.List<" + - union_name + ">;\n"; - code += " if (_olist != null) {\n"; - code += " writer.WriteStartArray();\n"; - code += - " foreach (var _o in _olist) { this.WriteJson(writer, _o, " - "serializer); }\n"; - code += " writer.WriteEndArray();\n"; - code += " } else {\n"; - code += " this.WriteJson(writer, value as " + union_name + - ", serializer);\n"; - code += " }\n"; - code += " }\n"; - code += " public void WriteJson(Newtonsoft.Json.JsonWriter writer, " + - union_name + - " _o, " - "Newtonsoft.Json.JsonSerializer serializer) {\n"; - code += " if (_o == null) return;\n"; - code += " serializer.Serialize(writer, _o.Value);\n"; - code += " }\n"; - code += - " public override object ReadJson(Newtonsoft.Json.JsonReader " - "reader, " - "System.Type objectType, " - "object existingValue, Newtonsoft.Json.JsonSerializer serializer) " - "{\n"; - code += - " var _olist = existingValue as System.Collections.Generic.List<" + - union_name + ">;\n"; - code += " if (_olist != null) {\n"; - code += " for (var _j = 0; _j < _olist.Count; ++_j) {\n"; - code += " reader.Read();\n"; - code += - " _olist[_j] = this.ReadJson(reader, _olist[_j], " - "serializer);\n"; - code += " }\n"; - code += " reader.Read();\n"; - code += " return _olist;\n"; - code += " } else {\n"; - code += " return this.ReadJson(reader, existingValue as " + - union_name + ", serializer);\n"; - code += " }\n"; - code += " }\n"; - code += " public " + union_name + - " ReadJson(Newtonsoft.Json.JsonReader reader, " + union_name + - " _o, Newtonsoft.Json.JsonSerializer serializer) {\n"; - code += " if (_o == null) return null;\n"; - code += " switch (_o.Type) {\n"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - auto &ev = **it; - if (ev.union_type.base_type == BASE_TYPE_NONE) { - code += " default: break;\n"; - } else { - auto type_name = GenTypeGet_ObjectAPI(ev.union_type, opts); - code += " case " + enum_def.name + "." + ev.name + - ": _o.Value = serializer.Deserialize<" + type_name + - ">(reader); break;\n"; - } - } - code += " }\n"; - code += " return _o;\n"; - code += " }\n"; - code += "}\n\n"; - } - } - - std::string GenTypeName_ObjectAPI(const std::string &name, - const IDLOptions &opts) const { - return opts.object_prefix + name + opts.object_suffix; - } - - void GenUnionUnPack_ObjectAPI(const EnumDef &enum_def, std::string *code_ptr, - const std::string &camel_name, - bool is_vector) const { - auto &code = *code_ptr; - std::string varialbe_name = "_o." + camel_name; - std::string type_suffix = ""; - std::string func_suffix = "()"; - std::string indent = " "; - if (is_vector) { - varialbe_name = "_o_" + camel_name; - type_suffix = "(_j)"; - func_suffix = "(_j)"; - indent = " "; - } - if (is_vector) { - code += indent + "var " + varialbe_name + " = new "; - } else { - code += indent + varialbe_name + " = new "; - } - code += WrapInNameSpace(enum_def) + "Union();\n"; - code += indent + varialbe_name + ".Type = this." + camel_name + "Type" + - type_suffix + ";\n"; - code += - indent + "switch (this." + camel_name + "Type" + type_suffix + ") {\n"; - for (auto eit = enum_def.Vals().begin(); eit != enum_def.Vals().end(); - ++eit) { - auto &ev = **eit; - if (ev.union_type.base_type == BASE_TYPE_NONE) { - code += indent + " default: break;\n"; - } else { - code += indent + " case " + WrapInNameSpace(enum_def) + "." + ev.name + - ":\n"; - code += indent + " " + varialbe_name + ".Value = this." + camel_name; - if (IsString(ev.union_type)) { - code += "AsString" + func_suffix + ";\n"; - } else { - code += "<" + GenTypeGet(ev.union_type) + ">" + func_suffix; - code += ".HasValue ? this." + camel_name; - code += "<" + GenTypeGet(ev.union_type) + ">" + func_suffix + - ".Value.UnPack() : null;\n"; - } - code += indent + " break;\n"; - } - } - code += indent + "}\n"; - if (is_vector) { - code += indent + "_o." + camel_name + ".Add(" + varialbe_name + ");\n"; - } - } - - void GenPackUnPack_ObjectAPI( - StructDef &struct_def, std::string *code_ptr, const IDLOptions &opts, - bool struct_has_create, - const std::set<FieldDef *> &field_has_create) const { - auto &code = *code_ptr; - auto struct_name = GenTypeName_ObjectAPI(struct_def.name, opts); - // UnPack() - code += " public " + struct_name + " UnPack() {\n"; - code += " var _o = new " + struct_name + "();\n"; - code += " this.UnPackTo(_o);\n"; - code += " return _o;\n"; - code += " }\n"; - // UnPackTo() - code += " public void UnPackTo(" + struct_name + " _o) {\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto camel_name = MakeCamel(field.name); - auto start = " _o." + camel_name + " = "; - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - auto fixed = struct_def.fixed && field.value.type.struct_def->fixed; - if (fixed) { - code += start + "this." + camel_name + ".UnPack();\n"; - } else { - code += start + "this." + camel_name + ".HasValue ? this." + - camel_name + ".Value.UnPack() : null;\n"; - } - break; - } - case BASE_TYPE_ARRAY: { - auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts); - auto length_str = NumToString(field.value.type.fixed_length); - auto unpack_method = field.value.type.struct_def == nullptr - ? "" - : field.value.type.struct_def->fixed - ? ".UnPack()" - : "?.UnPack()"; - code += start + "new " + type_name.substr(0, type_name.length() - 1) + - length_str + "];\n"; - code += " for (var _j = 0; _j < " + length_str + "; ++_j) { _o." + - camel_name + "[_j] = this." + camel_name + "(_j)" + - unpack_method + "; }\n"; - break; - } - case BASE_TYPE_VECTOR: - if (field.value.type.element == BASE_TYPE_UNION) { - code += start + "new " + - GenTypeGet_ObjectAPI(field.value.type, opts) + "();\n"; - code += " for (var _j = 0; _j < this." + camel_name + - "Length; ++_j) {\n"; - GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code_ptr, - camel_name, true); - code += " }\n"; - } else if (field.value.type.element != BASE_TYPE_UTYPE) { - auto fixed = field.value.type.struct_def == nullptr; - code += start + "new " + - GenTypeGet_ObjectAPI(field.value.type, opts) + "();\n"; - code += " for (var _j = 0; _j < this." + camel_name + - "Length; ++_j) {"; - code += "_o." + camel_name + ".Add("; - if (fixed) { - code += "this." + camel_name + "(_j)"; - } else { - code += "this." + camel_name + "(_j).HasValue ? this." + - camel_name + "(_j).Value.UnPack() : null"; - } - code += ");}\n"; - } - break; - case BASE_TYPE_UTYPE: break; - case BASE_TYPE_UNION: { - GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code_ptr, - camel_name, false); - break; - } - default: { - code += start + "this." + camel_name + ";\n"; - break; - } - } - } - code += " }\n"; - // Pack() - code += " public static " + GenOffsetType(struct_def) + - " Pack(FlatBufferBuilder builder, " + struct_name + " _o) {\n"; - code += " if (_o == null) return default(" + GenOffsetType(struct_def) + - ");\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto camel_name = MakeCamel(field.name); - // pre - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - if (!field.value.type.struct_def->fixed) { - code += " var _" + field.name + " = _o." + camel_name + - " == null ? default(" + - GenOffsetType(*field.value.type.struct_def) + - ") : " + GenTypeGet(field.value.type) + - ".Pack(builder, _o." + camel_name + ");\n"; - } else if (struct_def.fixed && struct_has_create) { - std::vector<FieldArrayLength> array_lengths; - FieldArrayLength tmp_array_length = { - field.name, - field.value.type.fixed_length, - }; - array_lengths.push_back(tmp_array_length); - GenStructPackDecl_ObjectAPI(*field.value.type.struct_def, code_ptr, - array_lengths); - } - break; - } - case BASE_TYPE_STRING: { - std::string create_string = - field.shared ? "CreateSharedString" : "CreateString"; - code += " var _" + field.name + " = _o." + camel_name + - " == null ? default(StringOffset) : " - "builder." + - create_string + "(_o." + camel_name + ");\n"; - break; - } - case BASE_TYPE_VECTOR: { - if (field_has_create.find(&field) != field_has_create.end()) { - auto property_name = camel_name; - auto gen_for_loop = true; - std::string array_name = "__" + field.name; - std::string array_type = ""; - std::string to_array = ""; - switch (field.value.type.element) { - case BASE_TYPE_STRING: { - std::string create_string = - field.shared ? "CreateSharedString" : "CreateString"; - array_type = "StringOffset"; - to_array += "builder." + create_string + "(_o." + - property_name + "[_j])"; - break; - } - case BASE_TYPE_STRUCT: - array_type = "Offset<" + GenTypeGet(field.value.type) + ">"; - to_array = GenTypeGet(field.value.type) + ".Pack(builder, _o." + - property_name + "[_j])"; - break; - case BASE_TYPE_UTYPE: - property_name = camel_name.substr(0, camel_name.size() - 4); - array_type = WrapInNameSpace(*field.value.type.enum_def); - to_array = "_o." + property_name + "[_j].Type"; - break; - case BASE_TYPE_UNION: - array_type = "int"; - to_array = WrapInNameSpace(*field.value.type.enum_def) + - "Union.Pack(builder, _o." + property_name + "[_j])"; - break; - default: gen_for_loop = false; break; - } - code += " var _" + field.name + " = default(VectorOffset);\n"; - code += " if (_o." + property_name + " != null) {\n"; - if (gen_for_loop) { - code += " var " + array_name + " = new " + array_type + - "[_o." + property_name + ".Count];\n"; - code += " for (var _j = 0; _j < " + array_name + - ".Length; ++_j) { "; - code += array_name + "[_j] = " + to_array + "; }\n"; - } else { - code += " var " + array_name + " = _o." + property_name + - ".ToArray();\n"; - } - code += " _" + field.name + " = Create" + camel_name + - "Vector(builder, " + array_name + ");\n"; - code += " }\n"; - } else { - auto pack_method = - field.value.type.struct_def == nullptr - ? "builder.Add" + GenMethod(field.value.type.VectorType()) + - "(_o." + camel_name + "[_j]);" - : GenTypeGet(field.value.type) + ".Pack(builder, _o." + - camel_name + "[_j]);"; - code += " var _" + field.name + " = default(VectorOffset);\n"; - code += " if (_o." + camel_name + " != null) {\n"; - code += " Start" + camel_name + "Vector(builder, _o." + - camel_name + ".Count);\n"; - code += " for (var _j = _o." + camel_name + - ".Count - 1; _j >= 0; --_j) { " + pack_method + " }\n"; - code += " _" + field.name + " = builder.EndVector();\n"; - code += " }\n"; - } - break; - } - case BASE_TYPE_ARRAY: { - if (field.value.type.struct_def != nullptr) { - std::vector<FieldArrayLength> array_lengths; - FieldArrayLength tmp_array_length = { - field.name, - field.value.type.fixed_length, - }; - array_lengths.push_back(tmp_array_length); - GenStructPackDecl_ObjectAPI(*field.value.type.struct_def, code_ptr, - array_lengths); - } else { - code += " var _" + field.name + " = _o." + camel_name + ";\n"; - } - break; - } - case BASE_TYPE_UNION: { - code += " var _" + field.name + "_type = _o." + camel_name + - " == null ? " + WrapInNameSpace(*field.value.type.enum_def) + - ".NONE : " + "_o." + camel_name + ".Type;\n"; - code += - " var _" + field.name + " = _o." + camel_name + - " == null ? 0 : " + GenTypeGet_ObjectAPI(field.value.type, opts) + - ".Pack(builder, _o." + camel_name + ");\n"; - break; - } - default: break; - } - } - if (struct_has_create) { - // Create - code += " return Create" + struct_def.name + "(\n"; - code += " builder"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto camel_name = MakeCamel(field.name); - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - if (struct_def.fixed) { - GenStructPackCall_ObjectAPI(*field.value.type.struct_def, - code_ptr, - " _" + field.name + "_"); - } else { - code += ",\n"; - if (field.value.type.struct_def->fixed) { - if (opts.generate_object_based_api) - code += " _o." + camel_name; - else - code += " " + GenTypeGet(field.value.type) + - ".Pack(builder, _o." + camel_name + ")"; - } else { - code += " _" + field.name; - } - } - break; - } - case BASE_TYPE_ARRAY: { - if (field.value.type.struct_def != nullptr) { - GenStructPackCall_ObjectAPI(*field.value.type.struct_def, - code_ptr, - " _" + field.name + "_"); - } else { - code += ",\n"; - code += " _" + field.name; - } - break; - } - case BASE_TYPE_UNION: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_UTYPE: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_VECTOR: { - code += ",\n"; - code += " _" + field.name; - break; - } - default: // scalar - code += ",\n"; - code += " _o." + camel_name; - break; - } - } - code += ");\n"; - } else { - // Start, End - code += " Start" + struct_def.name + "(builder);\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto camel_name = MakeCamel(field.name); - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - if (field.value.type.struct_def->fixed) { - code += " Add" + camel_name + "(builder, " + - GenTypeGet(field.value.type) + ".Pack(builder, _o." + - camel_name + "));\n"; - } else { - code += - " Add" + camel_name + "(builder, _" + field.name + ");\n"; - } - break; - } - case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_VECTOR: { - code += - " Add" + camel_name + "(builder, _" + field.name + ");\n"; - break; - } - case BASE_TYPE_UTYPE: break; - case BASE_TYPE_UNION: { - code += " Add" + camel_name + "Type(builder, _" + field.name + - "_type);\n"; - code += - " Add" + camel_name + "(builder, _" + field.name + ");\n"; - break; - } - // scalar - default: { - code += - " Add" + camel_name + "(builder, _o." + camel_name + ");\n"; - break; - } - } - } - code += " return End" + struct_def.name + "(builder);\n"; - } - code += " }\n"; - } - - void GenStructPackDecl_ObjectAPI( - const StructDef &struct_def, std::string *code_ptr, - std::vector<FieldArrayLength> &array_lengths) const { - auto &code = *code_ptr; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - auto is_array = IsArray(field.value.type); - const auto &field_type = - is_array ? field.value.type.VectorType() : field.value.type; - FieldArrayLength tmp_array_length = { - field.name, - field_type.fixed_length, - }; - array_lengths.push_back(tmp_array_length); - if (field_type.struct_def != nullptr) { - GenStructPackDecl_ObjectAPI(*field_type.struct_def, code_ptr, - array_lengths); - } else { - std::vector<FieldArrayLength> array_only_lengths; - for (size_t i = 0; i < array_lengths.size(); ++i) { - if (array_lengths[i].length > 0) { - array_only_lengths.push_back(array_lengths[i]); - } - } - std::string name; - for (size_t i = 0; i < array_lengths.size(); ++i) { - name += "_" + array_lengths[i].name; - } - code += " var " + name + " = "; - if (array_only_lengths.size() > 0) { - code += "new " + GenTypeBasic(field_type) + "["; - for (size_t i = 0; i < array_only_lengths.size(); ++i) { - if (i != 0) { code += ","; } - code += NumToString(array_only_lengths[i].length); - } - code += "];\n"; - code += " "; - // initialize array - for (size_t i = 0; i < array_only_lengths.size(); ++i) { - auto idx = "idx" + NumToString(i); - code += "for (var " + idx + " = 0; " + idx + " < " + - NumToString(array_only_lengths[i].length) + "; ++" + idx + - ") {"; - } - for (size_t i = 0; i < array_only_lengths.size(); ++i) { - auto idx = "idx" + NumToString(i); - if (i == 0) { - code += name + "[" + idx; - } else { - code += "," + idx; - } - } - code += "] = _o"; - for (size_t i = 0, j = 0; i < array_lengths.size(); ++i) { - code += "." + MakeCamel(array_lengths[i].name); - if (array_lengths[i].length <= 0) continue; - code += "[idx" + NumToString(j++) + "]"; - } - code += ";"; - for (size_t i = 0; i < array_only_lengths.size(); ++i) { - code += "}"; - } - } else { - code += "_o"; - for (size_t i = 0; i < array_lengths.size(); ++i) { - code += "." + MakeCamel(array_lengths[i].name); - } - code += ";"; - } - code += "\n"; - } - array_lengths.pop_back(); - } - } - - void GenStructPackCall_ObjectAPI(const StructDef &struct_def, - std::string *code_ptr, - std::string prefix) const { - auto &code = *code_ptr; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - const auto &field_type = field.value.type; - if (field_type.struct_def != nullptr) { - GenStructPackCall_ObjectAPI(*field_type.struct_def, code_ptr, - prefix + field.name + "_"); - } else { - code += ",\n"; - code += prefix + field.name; - } - } - } - - std::string GenTypeGet_ObjectAPI(flatbuffers::Type type, - const IDLOptions &opts) const { - auto type_name = GenTypeGet(type); - // Replace to ObjectBaseAPI Type Name - switch (type.base_type) { - case BASE_TYPE_STRUCT: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_VECTOR: { - if (type.struct_def != nullptr) { - auto type_name_length = type.struct_def->name.length(); - auto new_type_name = - GenTypeName_ObjectAPI(type.struct_def->name, opts); - type_name.replace(type_name.length() - type_name_length, - type_name_length, new_type_name); - } else if (type.element == BASE_TYPE_UNION) { - type_name = WrapInNameSpace(*type.enum_def) + "Union"; - } - break; - } - - case BASE_TYPE_UNION: { - type_name = WrapInNameSpace(*type.enum_def) + "Union"; - break; - } - default: break; - } - - switch (type.base_type) { - case BASE_TYPE_ARRAY: { - type_name = type_name + "[]"; - break; - } - case BASE_TYPE_VECTOR: { - type_name = "List<" + type_name + ">"; - break; - } - default: break; - } - return type_name; - } - - void GenStruct_ObjectAPI(StructDef &struct_def, std::string *code_ptr, - const IDLOptions &opts) const { - auto &code = *code_ptr; - if (struct_def.attributes.Lookup("private")) { - code += "internal "; - } else { - code += "public "; - } - if (struct_def.attributes.Lookup("csharp_partial")) { - // generate a partial class for this C# struct/table - code += "partial "; - } - auto class_name = GenTypeName_ObjectAPI(struct_def.name, opts); - code += "class " + class_name; - code += "\n{\n"; - // Generate Properties - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (field.value.type.base_type == BASE_TYPE_UTYPE) continue; - if (field.value.type.element == BASE_TYPE_UTYPE) continue; - auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts); - if (field.IsScalarOptional()) type_name += "?"; - auto camel_name = MakeCamel(field.name, true); - if (opts.cs_gen_json_serializer) { - if (IsUnion(field.value.type)) { - auto utype_name = WrapInNameSpace(*field.value.type.enum_def); - code += - " [Newtonsoft.Json.JsonProperty(\"" + field.name + "_type\")]\n"; - if (IsVector(field.value.type)) { - code += " private " + utype_name + "[] " + camel_name + "Type {\n"; - code += " get {\n"; - code += " if (this." + camel_name + " == null) return null;\n"; - code += " var _o = new " + utype_name + "[this." + camel_name + - ".Count];\n"; - code += - " for (var _j = 0; _j < _o.Length; ++_j) { _o[_j] = " - "this." + - camel_name + "[_j].Type; }\n"; - code += " return _o;\n"; - code += " }\n"; - code += " set {\n"; - code += " this." + camel_name + " = new List<" + utype_name + - "Union>();\n"; - code += " for (var _j = 0; _j < value.Length; ++_j) {\n"; - code += " var _o = new " + utype_name + "Union();\n"; - code += " _o.Type = value[_j];\n"; - code += " this." + camel_name + ".Add(_o);\n"; - code += " }\n"; - code += " }\n"; - code += " }\n"; - } else { - code += " private " + utype_name + " " + camel_name + "Type {\n"; - code += " get {\n"; - code += " return this." + camel_name + " != null ? this." + - camel_name + ".Type : " + utype_name + ".NONE;\n"; - code += " }\n"; - code += " set {\n"; - code += " this." + camel_name + " = new " + utype_name + - "Union();\n"; - code += " this." + camel_name + ".Type = value;\n"; - code += " }\n"; - code += " }\n"; - } - } - code += " [Newtonsoft.Json.JsonProperty(\"" + field.name + "\")]\n"; - if (IsUnion(field.value.type)) { - auto union_name = - (IsVector(field.value.type)) - ? GenTypeGet_ObjectAPI(field.value.type.VectorType(), opts) - : type_name; - code += " [Newtonsoft.Json.JsonConverter(typeof(" + union_name + - "_JsonConverter))]\n"; - } - if (field.attributes.Lookup("hash")) { - code += " [Newtonsoft.Json.JsonIgnore()]\n"; - } - } - code += " public " + type_name + " " + camel_name + " { get; set; }\n"; - } - // Generate Constructor - code += "\n"; - code += " public " + class_name + "() {\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (field.value.type.base_type == BASE_TYPE_UTYPE) continue; - if (field.value.type.element == BASE_TYPE_UTYPE) continue; - code += " this." + MakeCamel(field.name) + " = "; - auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts); - if (IsScalar(field.value.type.base_type)) { - code += GenDefaultValue(field) + ";\n"; - } else { - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - if (IsStruct(field.value.type)) { - code += "new " + type_name + "();\n"; - } else { - code += "null;\n"; - } - break; - } - case BASE_TYPE_ARRAY: { - code += "new " + type_name.substr(0, type_name.length() - 1) + - NumToString(field.value.type.fixed_length) + "];\n"; - break; - } - default: { - code += "null;\n"; - break; - } - } - } - } - code += " }\n"; - // Generate Serialization - if (opts.cs_gen_json_serializer && - parser_.root_struct_def_ == &struct_def) { - code += "\n"; - code += " public static " + class_name + - " DeserializeFromJson(string jsonText) {\n"; - code += " return Newtonsoft.Json.JsonConvert.DeserializeObject<" + - class_name + ">(jsonText);\n"; - code += " }\n"; - code += " public string SerializeToJson() {\n"; - code += - " return Newtonsoft.Json.JsonConvert.SerializeObject(this, " - "Newtonsoft.Json.Formatting.Indented);\n"; - code += " }\n"; - } - if (parser_.root_struct_def_ == &struct_def) { - code += " public static " + class_name + - " DeserializeFromBinary(byte[] fbBuffer) {\n"; - code += " return " + struct_def.name + ".GetRootAs" + struct_def.name + - "(new ByteBuffer(fbBuffer)).UnPack();\n"; - code += " }\n"; - code += " public byte[] SerializeToBinary() {\n"; - code += " var fbb = new FlatBufferBuilder(0x10000);\n"; - code += " " + struct_def.name + ".Finish" + struct_def.name + - "Buffer(fbb, " + struct_def.name + ".Pack(fbb, this));\n"; - code += " return fbb.DataBuffer.ToSizedArray();\n"; - code += " }\n"; - } - code += "}\n\n"; - } - - // This tracks the current namespace used to determine if a type need to be - // prefixed by its namespace - const Namespace *cur_name_space_; -}; -} // namespace csharp - -bool GenerateCSharp(const Parser &parser, const std::string &path, - const std::string &file_name) { - csharp::CSharpGenerator generator(parser, path, file_name); - return generator.generate(); -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_dart.cpp b/contrib/libs/flatbuffers/src/idl_gen_dart.cpp deleted file mode 100644 index 56c4a82555..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_dart.cpp +++ /dev/null @@ -1,955 +0,0 @@ -/* - * Copyright 2018 Dan Field - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// independent from idl_parser, since this code is not needed for most clients -#include <cassert> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -namespace dart { - -const std::string _kFb = "fb"; -// see https://www.dartlang.org/guides/language/language-tour#keywords -// yeild*, async*, and sync* shouldn't be problems anyway but keeping them in -static const char *keywords[] = { - "abstract", "deferred", "if", "super", "as", "do", - "implements", "switch", "assert", "dynamic", "import", "sync*", - "async", "else", "in", "this", "async*", "enum", - "is", "throw", "await", "export", "library", "true", - "break", "external", "new", "try", "case", "extends", - "null", "typedef", "catch", "factory", "operator", "var", - "class", "false", "part", "void", "const", "final", - "rethrow", "while", "continue", "finally", "return", "with", - "covariant", "for", "set", "yield", "default", "get", - "static", "yield*" -}; - -// Iterate through all definitions we haven't generate code for (enums, structs, -// and tables) and output them to a single file. -class DartGenerator : public BaseGenerator { - public: - typedef std::map<std::string, std::string> namespace_code_map; - - DartGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", ".", "dart") {} - // Iterate through all definitions we haven't generate code for (enums, - // structs, and tables) and output them to a single file. - bool generate() { - std::string code; - namespace_code_map namespace_code; - GenerateEnums(&namespace_code); - GenerateStructs(&namespace_code); - - for (auto kv = namespace_code.begin(); kv != namespace_code.end(); ++kv) { - code.clear(); - code = code + "// " + FlatBuffersGeneratedWarning() + "\n"; - code = code + - "// ignore_for_file: unused_import, unused_field, " - "unused_local_variable\n\n"; - - if (!kv->first.empty()) { code += "library " + kv->first + ";\n\n"; } - - code += "import 'dart:typed_data' show Uint8List;\n"; - code += "import 'package:flat_buffers/flat_buffers.dart' as " + _kFb + - ";\n\n"; - - for (auto kv2 = namespace_code.begin(); kv2 != namespace_code.end(); - ++kv2) { - if (kv2->first != kv->first) { - code += - "import '" + - GeneratedFileName( - "./", - file_name_ + (!kv2->first.empty() ? "_" + kv2->first : ""), - parser_.opts) + - "' as " + ImportAliasName(kv2->first) + ";\n"; - } - } - code += "\n"; - code += kv->second; - - if (!SaveFile( - GeneratedFileName( - path_, - file_name_ + (!kv->first.empty() ? "_" + kv->first : ""), - parser_.opts) - .c_str(), - code, false)) { - return false; - } - } - return true; - } - - private: - static std::string ImportAliasName(const std::string &ns) { - std::string ret; - ret.assign(ns); - size_t pos = ret.find('.'); - while (pos != std::string::npos) { - ret.replace(pos, 1, "_"); - pos = ret.find('.', pos + 1); - } - - return ret; - } - - static std::string BuildNamespaceName(const Namespace &ns) { - if (ns.components.empty()) { return ""; } - std::stringstream sstream; - std::copy(ns.components.begin(), ns.components.end() - 1, - std::ostream_iterator<std::string>(sstream, ".")); - - auto ret = sstream.str() + ns.components.back(); - for (size_t i = 0; i < ret.size(); i++) { - auto lower = CharToLower(ret[i]); - if (lower != ret[i]) { - ret[i] = lower; - if (i != 0 && ret[i - 1] != '.') { - ret.insert(i, "_"); - i++; - } - } - } - // std::transform(ret.begin(), ret.end(), ret.begin(), CharToLower); - return ret; - } - - void GenIncludeDependencies(std::string *code, - const std::string &the_namespace) { - for (auto it = parser_.included_files_.begin(); - it != parser_.included_files_.end(); ++it) { - if (it->second.empty()) continue; - - auto noext = flatbuffers::StripExtension(it->second); - auto basename = flatbuffers::StripPath(noext); - - *code += - "import '" + - GeneratedFileName( - "", basename + (the_namespace == "" ? "" : "_" + the_namespace), - parser_.opts) + - "';\n"; - } - } - - static std::string EscapeKeyword(const std::string &name) { - for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) { - if (name == keywords[i]) { return MakeCamel(name + "_", false); } - } - - return MakeCamel(name, false); - } - - void GenerateEnums(namespace_code_map *namespace_code) { - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - auto &enum_def = **it; - GenEnum(enum_def, namespace_code); // enum_code_ptr); - } - } - - void GenerateStructs(namespace_code_map *namespace_code) { - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - auto &struct_def = **it; - GenStruct(struct_def, namespace_code); - } - } - - // Generate a documentation comment, if available. - static void GenDocComment(const std::vector<std::string> &dc, - std::string *code_ptr, - const std::string &extra_lines, - const char *indent = nullptr) { - if (dc.empty() && extra_lines.empty()) { - // Don't output empty comment blocks with 0 lines of comment content. - return; - } - - auto &code = *code_ptr; - - for (auto it = dc.begin(); it != dc.end(); ++it) { - if (indent) code += indent; - code += "/// " + *it + "\n"; - } - if (!extra_lines.empty()) { - if (!dc.empty()) { - if (indent) code += indent; - code += "///\n"; - } - if (indent) code += indent; - std::string::size_type start = 0; - for (;;) { - auto end = extra_lines.find('\n', start); - if (end != std::string::npos) { - code += "/// " + extra_lines.substr(start, end - start) + "\n"; - start = end + 1; - } else { - code += "/// " + extra_lines.substr(start) + "\n"; - break; - } - } - } - } - - static void GenDocComment(std::string *code_ptr, - const std::string &extra_lines) { - GenDocComment(std::vector<std::string>(), code_ptr, extra_lines); - } - - // Generate an enum declaration and an enum string lookup table. - void GenEnum(EnumDef &enum_def, namespace_code_map *namespace_code) { - if (enum_def.generated) return; - auto ns = BuildNamespaceName(*enum_def.defined_namespace); - std::string code; - GenDocComment(enum_def.doc_comment, &code, ""); - - auto name = enum_def.is_union ? enum_def.name + "TypeId" : enum_def.name; - auto is_bit_flags = enum_def.attributes.Lookup("bit_flags"); - - code += "class " + name + " {\n"; - code += " final int value;\n"; - code += " const " + name + "._(this.value);\n\n"; - code += " factory " + name + ".fromValue(int value) {\n"; - code += " if (value == null) value = 0;\n"; - - code += " if (!values.containsKey(value)) {\n"; - code += - " throw new StateError('Invalid value $value for bit flag enum "; - code += name + "');\n"; - code += " }\n"; - - code += " return values[value];\n"; - code += " }\n\n"; - - // this is meaningless for bit_flags - // however, note that unlike "regular" dart enums this enum can still have - // holes. - if (!is_bit_flags) { - code += " static const int minValue = " + - enum_def.ToString(*enum_def.MinValue()) + ";\n"; - code += " static const int maxValue = " + - enum_def.ToString(*enum_def.MaxValue()) + ";\n"; - } - - code += - " static bool containsValue(int value) =>" - " values.containsKey(value);\n\n"; - - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - - if (!ev.doc_comment.empty()) { - if (it != enum_def.Vals().begin()) { code += '\n'; } - GenDocComment(ev.doc_comment, &code, "", " "); - } - code += " static const " + name + " " + ev.name + " = "; - code += "const " + name + "._(" + enum_def.ToString(ev) + ");\n"; - } - - code += " static const Map<int," + name + "> values = {"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - code += enum_def.ToString(ev) + ": " + ev.name + ","; - } - code += "};\n\n"; - - code += " static const " + _kFb + ".Reader<" + name + - "> reader = const _" + name + "Reader();\n\n"; - code += " @override\n"; - code += " String toString() {\n"; - code += " return '" + name + "{value: $value}';\n"; - code += " }\n"; - code += "}\n\n"; - - GenEnumReader(enum_def, name, &code); - (*namespace_code)[ns] += code; - } - - void GenEnumReader(EnumDef &enum_def, const std::string &name, - std::string *code_ptr) { - auto &code = *code_ptr; - - code += "class _" + name + "Reader extends " + _kFb + ".Reader<" + name + - "> {\n"; - code += " const _" + name + "Reader();\n\n"; - code += " @override\n"; - code += " int get size => 1;\n\n"; - code += " @override\n"; - code += - " " + name + " read(" + _kFb + ".BufferContext bc, int offset) =>\n"; - code += " new " + name + ".fromValue(const " + _kFb + "." + - GenType(enum_def.underlying_type) + "Reader().read(bc, offset));\n"; - code += "}\n\n"; - } - - static std::string GenType(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_BOOL: return "Bool"; - case BASE_TYPE_CHAR: return "Int8"; - case BASE_TYPE_UTYPE: - case BASE_TYPE_UCHAR: return "Uint8"; - case BASE_TYPE_SHORT: return "Int16"; - case BASE_TYPE_USHORT: return "Uint16"; - case BASE_TYPE_INT: return "Int32"; - case BASE_TYPE_UINT: return "Uint32"; - case BASE_TYPE_LONG: return "Int64"; - case BASE_TYPE_ULONG: return "Uint64"; - case BASE_TYPE_FLOAT: return "Float32"; - case BASE_TYPE_DOUBLE: return "Float64"; - case BASE_TYPE_STRING: return "String"; - case BASE_TYPE_VECTOR: return GenType(type.VectorType()); - case BASE_TYPE_STRUCT: return type.struct_def->name; - case BASE_TYPE_UNION: return type.enum_def->name + "TypeId"; - default: return "Table"; - } - } - - std::string GenReaderTypeName(const Type &type, Namespace *current_namespace, - const FieldDef &def, - bool parent_is_vector = false) { - if (type.base_type == BASE_TYPE_BOOL) { - return "const " + _kFb + ".BoolReader()"; - } else if (IsVector(type)) { - return "const " + _kFb + ".ListReader<" + - GenDartTypeName(type.VectorType(), current_namespace, def) + ">(" + - GenReaderTypeName(type.VectorType(), current_namespace, def, - true) + - ")"; - } else if (IsString(type)) { - return "const " + _kFb + ".StringReader()"; - } - if (IsScalar(type.base_type)) { - if (type.enum_def && parent_is_vector) { - return GenDartTypeName(type, current_namespace, def) + ".reader"; - } - return "const " + _kFb + "." + GenType(type) + "Reader()"; - } else { - return GenDartTypeName(type, current_namespace, def) + ".reader"; - } - } - - std::string GenDartTypeName(const Type &type, Namespace *current_namespace, - const FieldDef &def, bool addBuilder = false) { - if (type.enum_def) { - if (type.enum_def->is_union && type.base_type != BASE_TYPE_UNION) { - return type.enum_def->name + "TypeId"; - } else if (type.enum_def->is_union) { - return "dynamic"; - } else if (type.base_type != BASE_TYPE_VECTOR) { - return type.enum_def->name; - } - } - - switch (type.base_type) { - case BASE_TYPE_BOOL: return "bool"; - case BASE_TYPE_LONG: - case BASE_TYPE_ULONG: - case BASE_TYPE_INT: - case BASE_TYPE_UINT: - case BASE_TYPE_SHORT: - case BASE_TYPE_USHORT: - case BASE_TYPE_CHAR: - case BASE_TYPE_UCHAR: return "int"; - case BASE_TYPE_FLOAT: - case BASE_TYPE_DOUBLE: return "double"; - case BASE_TYPE_STRING: return "String"; - case BASE_TYPE_STRUCT: - return MaybeWrapNamespace( - type.struct_def->name + (addBuilder ? "ObjectBuilder" : ""), - current_namespace, def); - case BASE_TYPE_VECTOR: - return "List<" + - GenDartTypeName(type.VectorType(), current_namespace, def, - addBuilder) + - ">"; - default: assert(0); return "dynamic"; - } - } - - static const std::string MaybeWrapNamespace(const std::string &type_name, - Namespace *current_ns, - const FieldDef &field) { - auto curr_ns_str = BuildNamespaceName(*current_ns); - std::string field_ns_str = ""; - if (field.value.type.struct_def) { - field_ns_str += - BuildNamespaceName(*field.value.type.struct_def->defined_namespace); - } else if (field.value.type.enum_def) { - field_ns_str += - BuildNamespaceName(*field.value.type.enum_def->defined_namespace); - } - - if (field_ns_str != "" && field_ns_str != curr_ns_str) { - return ImportAliasName(field_ns_str) + "." + type_name; - } else { - return type_name; - } - } - - // Generate an accessor struct with constructor for a flatbuffers struct. - void GenStruct(const StructDef &struct_def, - namespace_code_map *namespace_code) { - if (struct_def.generated) return; - - auto object_namespace = BuildNamespaceName(*struct_def.defined_namespace); - std::string code; - - const auto &object_name = struct_def.name; - - // Emit constructor - - GenDocComment(struct_def.doc_comment, &code, ""); - - auto reader_name = "_" + object_name + "Reader"; - auto builder_name = object_name + "Builder"; - auto object_builder_name = object_name + "ObjectBuilder"; - - std::string reader_code, builder_code; - - code += "class " + object_name + " {\n"; - - code += " " + object_name + "._(this._bc, this._bcOffset);\n"; - if (!struct_def.fixed) { - code += " factory " + object_name + "(List<int> bytes) {\n"; - code += " " + _kFb + ".BufferContext rootRef = new " + _kFb + - ".BufferContext.fromBytes(bytes);\n"; - code += " return reader.read(rootRef, 0);\n"; - code += " }\n"; - } - - code += "\n"; - code += " static const " + _kFb + ".Reader<" + object_name + - "> reader = const " + reader_name + "();\n\n"; - - code += " final " + _kFb + ".BufferContext _bc;\n"; - code += " final int _bcOffset;\n\n"; - - std::vector<std::pair<int, FieldDef *>> non_deprecated_fields; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto offset = static_cast<int>(it - struct_def.fields.vec.begin()); - non_deprecated_fields.push_back(std::make_pair(offset, &field)); - } - - GenImplementationGetters(struct_def, non_deprecated_fields, &code); - - code += "}\n\n"; - - GenReader(struct_def, &reader_name, &reader_code); - GenBuilder(struct_def, non_deprecated_fields, &builder_name, &builder_code); - GenObjectBuilder(struct_def, non_deprecated_fields, &object_builder_name, - &builder_code); - - code += reader_code; - code += builder_code; - - (*namespace_code)[object_namespace] += code; - } - - std::string NamespaceAliasFromUnionType(Namespace *root_namespace, - const Type &type) { - const std::vector<std::string> qualified_name_parts = - type.struct_def->defined_namespace->components; - if (std::equal(root_namespace->components.begin(), - root_namespace->components.end(), - qualified_name_parts.begin())) { - return type.struct_def->name; - } - - std::string ns; - - for (auto it = qualified_name_parts.begin(); - it != qualified_name_parts.end(); ++it) { - auto &part = *it; - - for (size_t i = 0; i < part.length(); i++) { - if (i && !isdigit(part[i]) && part[i] == CharToUpper(part[i])) { - ns += "_"; - ns += CharToLower(part[i]); - } else { - ns += CharToLower(part[i]); - } - } - if (it != qualified_name_parts.end() - 1) { ns += "_"; } - } - - return ns + "." + type.struct_def->name; - } - - void GenImplementationGetters( - const StructDef &struct_def, - std::vector<std::pair<int, FieldDef *>> non_deprecated_fields, - std::string *code_ptr) { - auto &code = *code_ptr; - - for (auto it = non_deprecated_fields.begin(); - it != non_deprecated_fields.end(); ++it) { - auto pair = *it; - auto &field = *pair.second; - - std::string field_name = MakeCamel(field.name, false); - std::string type_name = GenDartTypeName( - field.value.type, struct_def.defined_namespace, field, false); - - GenDocComment(field.doc_comment, &code, "", " "); - - code += " " + type_name + " get " + field_name; - if (field.value.type.base_type == BASE_TYPE_UNION) { - code += " {\n"; - code += " switch (" + field_name + "Type?.value) {\n"; - auto &enum_def = *field.value.type.enum_def; - for (auto en_it = enum_def.Vals().begin() + 1; - en_it != enum_def.Vals().end(); ++en_it) { - auto &ev = **en_it; - - auto enum_name = NamespaceAliasFromUnionType( - enum_def.defined_namespace, ev.union_type); - code += " case " + enum_def.ToString(ev) + ": return " + - enum_name + ".reader.vTableGet(_bc, _bcOffset, " + - NumToString(field.value.offset) + ", null);\n"; - } - code += " default: return null;\n"; - code += " }\n"; - code += " }\n"; - } else { - code += " => "; - if (field.value.type.enum_def && - field.value.type.base_type != BASE_TYPE_VECTOR) { - code += "new " + - GenDartTypeName(field.value.type, - struct_def.defined_namespace, field) + - ".fromValue("; - } - - code += GenReaderTypeName(field.value.type, - struct_def.defined_namespace, field); - if (struct_def.fixed) { - code += - ".read(_bc, _bcOffset + " + NumToString(field.value.offset) + ")"; - } else { - code += ".vTableGet(_bc, _bcOffset, " + - NumToString(field.value.offset) + ", "; - if (!field.value.constant.empty() && field.value.constant != "0") { - if (IsBool(field.value.type.base_type)) { - code += "true"; - } else if (field.value.constant == "nan" || - field.value.constant == "+nan" || - field.value.constant == "-nan") { - code += "double.nan"; - } else if (field.value.constant == "inf" || - field.value.constant == "+inf") { - code += "double.infinity"; - } else if (field.value.constant == "-inf") { - code += "double.negativeInfinity"; - } else { - code += field.value.constant; - } - } else { - if (IsBool(field.value.type.base_type)) { - code += "false"; - } else if (IsScalar(field.value.type.base_type)) { - code += "0"; - } else { - code += "null"; - } - } - code += ")"; - } - if (field.value.type.enum_def && - field.value.type.base_type != BASE_TYPE_VECTOR) { - code += ")"; - } - code += ";\n"; - } - } - - code += "\n"; - - code += " @override\n"; - code += " String toString() {\n"; - code += " return '" + struct_def.name + "{"; - for (auto it = non_deprecated_fields.begin(); - it != non_deprecated_fields.end(); ++it) { - auto pair = *it; - auto &field = *pair.second; - code += - MakeCamel(field.name, false) + ": $" + MakeCamel(field.name, false); - if (it != non_deprecated_fields.end() - 1) { code += ", "; } - } - code += "}';\n"; - code += " }\n"; - } - - void GenReader(const StructDef &struct_def, std::string *reader_name_ptr, - std::string *code_ptr) { - auto &code = *code_ptr; - auto &reader_name = *reader_name_ptr; - auto &impl_name = struct_def.name; - - code += "class " + reader_name + " extends " + _kFb; - if (struct_def.fixed) { - code += ".StructReader<"; - } else { - code += ".TableReader<"; - } - code += impl_name + "> {\n"; - code += " const " + reader_name + "();\n\n"; - - if (struct_def.fixed) { - code += " @override\n"; - code += " int get size => " + NumToString(struct_def.bytesize) + ";\n\n"; - } - code += " @override\n"; - code += " " + impl_name + - " createObject(fb.BufferContext bc, int offset) => \n new " + - impl_name + "._(bc, offset);\n"; - code += "}\n\n"; - } - - void GenBuilder(const StructDef &struct_def, - std::vector<std::pair<int, FieldDef *>> non_deprecated_fields, - std::string *builder_name_ptr, std::string *code_ptr) { - if (non_deprecated_fields.size() == 0) { return; } - auto &code = *code_ptr; - auto &builder_name = *builder_name_ptr; - - code += "class " + builder_name + " {\n"; - code += " " + builder_name + "(this.fbBuilder) {\n"; - code += " assert(fbBuilder != null);\n"; - code += " }\n\n"; - code += " final " + _kFb + ".Builder fbBuilder;\n\n"; - - if (struct_def.fixed) { - StructBuilderBody(struct_def, non_deprecated_fields, code_ptr); - } else { - TableBuilderBody(struct_def, non_deprecated_fields, code_ptr); - } - - code += "}\n\n"; - } - - void StructBuilderBody( - const StructDef &struct_def, - std::vector<std::pair<int, FieldDef *>> non_deprecated_fields, - std::string *code_ptr) { - auto &code = *code_ptr; - - code += " int finish("; - for (auto it = non_deprecated_fields.begin(); - it != non_deprecated_fields.end(); ++it) { - auto pair = *it; - auto &field = *pair.second; - - if (IsStruct(field.value.type)) { - code += "fb.StructBuilder"; - } else { - code += GenDartTypeName(field.value.type, struct_def.defined_namespace, - field); - } - code += " " + field.name; - if (it != non_deprecated_fields.end() - 1) { code += ", "; } - } - code += ") {\n"; - - for (auto it = non_deprecated_fields.rbegin(); - it != non_deprecated_fields.rend(); ++it) { - auto pair = *it; - auto &field = *pair.second; - - if (field.padding) { - code += " fbBuilder.pad(" + NumToString(field.padding) + ");\n"; - } - - if (IsStruct(field.value.type)) { - code += " " + field.name + "();\n"; - } else { - code += " fbBuilder.put" + GenType(field.value.type) + "("; - code += field.name; - if (field.value.type.enum_def) { code += "?.value"; } - code += ");\n"; - } - } - code += " return fbBuilder.offset;\n"; - code += " }\n\n"; - } - - void TableBuilderBody( - const StructDef &struct_def, - std::vector<std::pair<int, FieldDef *>> non_deprecated_fields, - std::string *code_ptr) { - auto &code = *code_ptr; - - code += " void begin() {\n"; - code += " fbBuilder.startTable();\n"; - code += " }\n\n"; - - for (auto it = non_deprecated_fields.begin(); - it != non_deprecated_fields.end(); ++it) { - auto pair = *it; - auto &field = *pair.second; - auto offset = pair.first; - - if (IsScalar(field.value.type.base_type)) { - code += " int add" + MakeCamel(field.name) + "("; - code += GenDartTypeName(field.value.type, struct_def.defined_namespace, - field); - code += " " + MakeCamel(field.name, false) + ") {\n"; - code += " fbBuilder.add" + GenType(field.value.type) + "(" + - NumToString(offset) + ", "; - code += MakeCamel(field.name, false); - if (field.value.type.enum_def) { code += "?.value"; } - code += ");\n"; - } else if (IsStruct(field.value.type)) { - code += " int add" + MakeCamel(field.name) + "(int offset) {\n"; - code += - " fbBuilder.addStruct(" + NumToString(offset) + ", offset);\n"; - } else { - code += " int add" + MakeCamel(field.name) + "Offset(int offset) {\n"; - code += - " fbBuilder.addOffset(" + NumToString(offset) + ", offset);\n"; - } - code += " return fbBuilder.offset;\n"; - code += " }\n"; - } - - code += "\n"; - code += " int finish() {\n"; - code += " return fbBuilder.endTable();\n"; - code += " }\n"; - } - - void GenObjectBuilder( - const StructDef &struct_def, - std::vector<std::pair<int, FieldDef *>> non_deprecated_fields, - std::string *builder_name_ptr, std::string *code_ptr) { - auto &code = *code_ptr; - auto &builder_name = *builder_name_ptr; - - code += "class " + builder_name + " extends " + _kFb + ".ObjectBuilder {\n"; - for (auto it = non_deprecated_fields.begin(); - it != non_deprecated_fields.end(); ++it) { - auto pair = *it; - auto &field = *pair.second; - - code += " final " + - GenDartTypeName(field.value.type, struct_def.defined_namespace, - field, true) + - " _" + MakeCamel(field.name, false) + ";\n"; - } - code += "\n"; - code += " " + builder_name + "("; - - if (non_deprecated_fields.size() != 0) { - code += "{\n"; - for (auto it = non_deprecated_fields.begin(); - it != non_deprecated_fields.end(); ++it) { - auto pair = *it; - auto &field = *pair.second; - - code += " " + - GenDartTypeName(field.value.type, struct_def.defined_namespace, - field, true) + - " " + MakeCamel(field.name, false) + ",\n"; - } - code += " })\n"; - code += " : "; - for (auto it = non_deprecated_fields.begin(); - it != non_deprecated_fields.end(); ++it) { - auto pair = *it; - auto &field = *pair.second; - - code += "_" + MakeCamel(field.name, false) + " = " + - MakeCamel(field.name, false); - if (it == non_deprecated_fields.end() - 1) { - code += ";\n\n"; - } else { - code += ",\n "; - } - } - } else { - code += ");\n\n"; - } - - code += " /// Finish building, and store into the [fbBuilder].\n"; - code += " @override\n"; - code += " int finish(\n"; - code += " " + _kFb + ".Builder fbBuilder) {\n"; - code += " assert(fbBuilder != null);\n"; - - for (auto it = non_deprecated_fields.begin(); - it != non_deprecated_fields.end(); ++it) { - auto pair = *it; - auto &field = *pair.second; - - if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type)) - continue; - - code += " final int " + MakeCamel(field.name, false) + "Offset"; - if (IsVector(field.value.type)) { - code += - " = _" + MakeCamel(field.name, false) + "?.isNotEmpty == true\n"; - code += " ? fbBuilder.writeList"; - switch (field.value.type.VectorType().base_type) { - case BASE_TYPE_STRING: - code += "(_" + MakeCamel(field.name, false) + - ".map((b) => fbBuilder.writeString(b)).toList())"; - break; - case BASE_TYPE_STRUCT: - if (field.value.type.struct_def->fixed) { - code += "OfStructs(_" + MakeCamel(field.name, false) + ")"; - } else { - code += "(_" + MakeCamel(field.name, false) + - ".map((b) => b.getOrCreateOffset(fbBuilder)).toList())"; - } - break; - default: - code += GenType(field.value.type.VectorType()) + "(_" + - MakeCamel(field.name, false); - if (field.value.type.enum_def) { code += ".map((f) => f.value)"; } - code += ")"; - } - code += "\n : null;\n"; - } else if (IsString(field.value.type)) { - code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) + - ");\n"; - } else { - code += " = _" + MakeCamel(field.name, false) + - "?.getOrCreateOffset(fbBuilder);\n"; - } - } - - code += "\n"; - if (struct_def.fixed) { - StructObjectBuilderBody(non_deprecated_fields, code_ptr); - } else { - TableObjectBuilderBody(non_deprecated_fields, code_ptr); - } - code += " }\n\n"; - - code += " /// Convenience method to serialize to byte list.\n"; - code += " @override\n"; - code += " Uint8List toBytes([String fileIdentifier]) {\n"; - code += " " + _kFb + ".Builder fbBuilder = new "; - code += _kFb + ".Builder();\n"; - code += " int offset = finish(fbBuilder);\n"; - code += " return fbBuilder.finish(offset, fileIdentifier);\n"; - code += " }\n"; - code += "}\n"; - } - - void StructObjectBuilderBody( - std::vector<std::pair<int, FieldDef *>> non_deprecated_fields, - std::string *code_ptr, bool prependUnderscore = true) { - auto &code = *code_ptr; - - for (auto it = non_deprecated_fields.rbegin(); - it != non_deprecated_fields.rend(); ++it) { - auto pair = *it; - auto &field = *pair.second; - - if (field.padding) { - code += " fbBuilder.pad(" + NumToString(field.padding) + ");\n"; - } - - if (IsStruct(field.value.type)) { - code += " "; - if (prependUnderscore) { code += "_"; } - code += field.name + ".finish(fbBuilder);\n"; - } else { - code += " fbBuilder.put" + GenType(field.value.type) + "("; - if (prependUnderscore) { code += "_"; } - code += field.name; - if (field.value.type.enum_def) { code += "?.value"; } - code += ");\n"; - } - } - - code += " return fbBuilder.offset;\n"; - } - - void TableObjectBuilderBody( - std::vector<std::pair<int, FieldDef *>> non_deprecated_fields, - std::string *code_ptr, bool prependUnderscore = true) { - std::string &code = *code_ptr; - code += " fbBuilder.startTable();\n"; - - for (auto it = non_deprecated_fields.begin(); - it != non_deprecated_fields.end(); ++it) { - auto pair = *it; - auto &field = *pair.second; - auto offset = pair.first; - - if (IsScalar(field.value.type.base_type)) { - code += " fbBuilder.add" + GenType(field.value.type) + "(" + - NumToString(offset) + ", "; - if (prependUnderscore) { code += "_"; } - code += MakeCamel(field.name, false); - if (field.value.type.enum_def) { code += "?.value"; } - code += ");\n"; - } else if (IsStruct(field.value.type)) { - code += " if ("; - if (prependUnderscore) { code += "_"; } - code += MakeCamel(field.name, false) + " != null) {\n"; - code += " fbBuilder.addStruct(" + NumToString(offset) + ", "; - code += "_" + MakeCamel(field.name, false) + ".finish(fbBuilder));\n"; - code += " }\n"; - } else { - code += - " if (" + MakeCamel(field.name, false) + "Offset != null) {\n"; - code += " fbBuilder.addOffset(" + NumToString(offset) + ", " + - MakeCamel(field.name, false) + "Offset);\n"; - code += " }\n"; - } - } - code += " return fbBuilder.endTable();\n"; - } -}; -} // namespace dart - -bool GenerateDart(const Parser &parser, const std::string &path, - const std::string &file_name) { - dart::DartGenerator generator(parser, path, file_name); - return generator.generate(); -} - -std::string DartMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name) { - assert(parser.opts.lang <= IDLOptions::kMAX); - - auto filebase = - flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); - dart::DartGenerator generator(parser, path, file_name); - auto make_rule = - generator.GeneratedFileName(path, file_name, parser.opts) + ": "; - - auto included_files = parser.GetIncludedFilesRecursive(file_name); - for (auto it = included_files.begin(); it != included_files.end(); ++it) { - make_rule += " " + *it; - } - return make_rule; -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_fbs.cpp b/contrib/libs/flatbuffers/src/idl_gen_fbs.cpp deleted file mode 100644 index 35c1a7d4f5..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_fbs.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -static std::string GenType(const Type &type, bool underlying = false) { - switch (type.base_type) { - case BASE_TYPE_STRUCT: - return type.struct_def->defined_namespace->GetFullyQualifiedName( - type.struct_def->name); - case BASE_TYPE_VECTOR: return "[" + GenType(type.VectorType()) + "]"; - default: - if (type.enum_def && !underlying) { - return type.enum_def->defined_namespace->GetFullyQualifiedName( - type.enum_def->name); - } else { - return kTypeNames[type.base_type]; - } - } -} - -static void GenNameSpace(const Namespace &name_space, std::string *_schema, - const Namespace **last_namespace) { - if (*last_namespace == &name_space) return; - *last_namespace = &name_space; - auto &schema = *_schema; - schema += "namespace "; - for (auto it = name_space.components.begin(); - it != name_space.components.end(); ++it) { - if (it != name_space.components.begin()) schema += "."; - schema += *it; - } - schema += ";\n\n"; -} - -// Generate a flatbuffer schema from the Parser's internal representation. -std::string GenerateFBS(const Parser &parser, const std::string &file_name) { - // Proto namespaces may clash with table names, escape the ones that were - // generated from a table: - for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end(); - ++it) { - auto &ns = **it; - for (size_t i = 0; i < ns.from_table; i++) { - ns.components[ns.components.size() - 1 - i] += "_"; - } - - if (parser.opts.proto_mode && !parser.opts.proto_namespace_suffix.empty()) { - // Since we know that all these namespaces come from a .proto, and all are - // being converted, we can simply apply this suffix to all of them. - ns.components.insert(ns.components.end() - ns.from_table, - parser.opts.proto_namespace_suffix); - } - } - - std::string schema; - schema += "// Generated from " + file_name + ".proto\n\n"; - if (parser.opts.include_dependence_headers) { - // clang-format off - int num_includes = 0; - for (auto it = parser.included_files_.begin(); - it != parser.included_files_.end(); ++it) { - if (it->second.empty()) - continue; - std::string basename; - if(parser.opts.keep_include_path) { - basename = flatbuffers::StripExtension(it->second); - } else { - basename = flatbuffers::StripPath( - flatbuffers::StripExtension(it->second)); - } - schema += "include \"" + basename + ".fbs\";\n"; - num_includes++; - } - if (num_includes) schema += "\n"; - // clang-format on - } - // Generate code for all the enum declarations. - const Namespace *last_namespace = nullptr; - for (auto enum_def_it = parser.enums_.vec.begin(); - enum_def_it != parser.enums_.vec.end(); ++enum_def_it) { - EnumDef &enum_def = **enum_def_it; - if (parser.opts.include_dependence_headers && enum_def.generated) { - continue; - } - GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace); - GenComment(enum_def.doc_comment, &schema, nullptr); - if (enum_def.is_union) - schema += "union " + enum_def.name; - else - schema += "enum " + enum_def.name + " : "; - schema += GenType(enum_def.underlying_type, true) + " {\n"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - GenComment(ev.doc_comment, &schema, nullptr, " "); - if (enum_def.is_union) - schema += " " + GenType(ev.union_type) + ",\n"; - else - schema += " " + ev.name + " = " + enum_def.ToString(ev) + ",\n"; - } - schema += "}\n\n"; - } - // Generate code for all structs/tables. - for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end(); - ++it) { - StructDef &struct_def = **it; - if (parser.opts.include_dependence_headers && struct_def.generated) { - continue; - } - GenNameSpace(*struct_def.defined_namespace, &schema, &last_namespace); - GenComment(struct_def.doc_comment, &schema, nullptr); - schema += "table " + struct_def.name + " {\n"; - for (auto field_it = struct_def.fields.vec.begin(); - field_it != struct_def.fields.vec.end(); ++field_it) { - auto &field = **field_it; - if (field.value.type.base_type != BASE_TYPE_UTYPE) { - GenComment(field.doc_comment, &schema, nullptr, " "); - schema += " " + field.name + ":" + GenType(field.value.type); - if (field.value.constant != "0") schema += " = " + field.value.constant; - if (field.IsRequired()) schema += " (required)"; - schema += ";\n"; - } - } - schema += "}\n\n"; - } - return schema; -} - -bool GenerateFBS(const Parser &parser, const std::string &path, - const std::string &file_name) { - return SaveFile((path + file_name + ".fbs").c_str(), - GenerateFBS(parser, file_name), false); -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_go.cpp b/contrib/libs/flatbuffers/src/idl_gen_go.cpp deleted file mode 100644 index 867f402322..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_go.cpp +++ /dev/null @@ -1,1374 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include <sstream> -#include <string> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -#ifdef _WIN32 -# include <direct.h> -# define PATH_SEPARATOR "\\" -# define mkdir(n, m) _mkdir(n) -#else -# include <sys/stat.h> -# define PATH_SEPARATOR "/" -#endif - -namespace flatbuffers { - -namespace go { - -// see https://golang.org/ref/spec#Keywords -static const char *const g_golang_keywords[] = { - "break", "default", "func", "interface", "select", "case", "defer", - "go", "map", "struct", "chan", "else", "goto", "package", - "switch", "const", "fallthrough", "if", "range", "type", "continue", - "for", "import", "return", "var", -}; - -static std::string GoIdentity(const std::string &name) { - for (size_t i = 0; - i < sizeof(g_golang_keywords) / sizeof(g_golang_keywords[0]); i++) { - if (name == g_golang_keywords[i]) { return MakeCamel(name + "_", false); } - } - - return MakeCamel(name, false); -} - -class GoGenerator : public BaseGenerator { - public: - GoGenerator(const Parser &parser, const std::string &path, - const std::string &file_name, const std::string &go_namespace) - : BaseGenerator(parser, path, file_name, "" /* not used*/, - "" /* not used */, "go"), - cur_name_space_(nullptr) { - std::istringstream iss(go_namespace); - std::string component; - while (std::getline(iss, component, '.')) { - go_namespace_.components.push_back(component); - } - } - - bool generate() { - std::string one_file_code; - bool needs_imports = false; - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - tracked_imported_namespaces_.clear(); - needs_imports = false; - std::string enumcode; - GenEnum(**it, &enumcode); - if ((*it)->is_union && parser_.opts.generate_object_based_api) { - GenNativeUnion(**it, &enumcode); - GenNativeUnionPack(**it, &enumcode); - GenNativeUnionUnPack(**it, &enumcode); - needs_imports = true; - } - if (parser_.opts.one_file) { - one_file_code += enumcode; - } else { - if (!SaveType(**it, enumcode, needs_imports, true)) return false; - } - } - - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - tracked_imported_namespaces_.clear(); - std::string declcode; - GenStruct(**it, &declcode); - if (parser_.opts.one_file) { - one_file_code += declcode; - } else { - if (!SaveType(**it, declcode, true, false)) return false; - } - } - - if (parser_.opts.one_file) { - std::string code = ""; - const bool is_enum = !parser_.enums_.vec.empty(); - BeginFile(LastNamespacePart(go_namespace_), true, is_enum, &code); - code += one_file_code; - const std::string filename = - GeneratedFileName(path_, file_name_, parser_.opts); - return SaveFile(filename.c_str(), code, false); - } - - return true; - } - - private: - Namespace go_namespace_; - Namespace *cur_name_space_; - - struct NamespacePtrLess { - bool operator()(const Namespace *a, const Namespace *b) const { - return *a < *b; - } - }; - std::set<const Namespace *, NamespacePtrLess> tracked_imported_namespaces_; - - // Most field accessors need to retrieve and test the field offset first, - // this is the prefix code for that. - std::string OffsetPrefix(const FieldDef &field) { - return "{\n\to := flatbuffers.UOffsetT(rcv._tab.Offset(" + - NumToString(field.value.offset) + "))\n\tif o != 0 {\n"; - } - - // Begin a class declaration. - void BeginClass(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "type " + struct_def.name + " struct {\n\t"; - - // _ is reserved in flatbuffers field names, so no chance of name conflict: - code += "_tab "; - code += struct_def.fixed ? "flatbuffers.Struct" : "flatbuffers.Table"; - code += "\n}\n\n"; - } - - // Construct the name of the type for this enum. - std::string GetEnumTypeName(const EnumDef &enum_def) { - return WrapInNameSpaceAndTrack(enum_def.defined_namespace, - GoIdentity(enum_def.name)); - } - - // Create a type for the enum values. - void GenEnumType(const EnumDef &enum_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "type " + GetEnumTypeName(enum_def) + " "; - code += GenTypeBasic(enum_def.underlying_type) + "\n\n"; - } - - // Begin enum code with a class declaration. - void BeginEnum(std::string *code_ptr) { - std::string &code = *code_ptr; - code += "const (\n"; - } - - // A single enum member. - void EnumMember(const EnumDef &enum_def, const EnumVal &ev, - size_t max_name_length, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "\t"; - code += enum_def.name; - code += ev.name; - code += " "; - code += std::string(max_name_length - ev.name.length(), ' '); - code += GetEnumTypeName(enum_def); - code += " = "; - code += enum_def.ToString(ev) + "\n"; - } - - // End enum code. - void EndEnum(std::string *code_ptr) { - std::string &code = *code_ptr; - code += ")\n\n"; - } - - // Begin enum name map. - void BeginEnumNames(const EnumDef &enum_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "var EnumNames"; - code += enum_def.name; - code += " = map[" + GetEnumTypeName(enum_def) + "]string{\n"; - } - - // A single enum name member. - void EnumNameMember(const EnumDef &enum_def, const EnumVal &ev, - size_t max_name_length, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "\t"; - code += enum_def.name; - code += ev.name; - code += ": "; - code += std::string(max_name_length - ev.name.length(), ' '); - code += "\""; - code += ev.name; - code += "\",\n"; - } - - // End enum name map. - void EndEnumNames(std::string *code_ptr) { - std::string &code = *code_ptr; - code += "}\n\n"; - } - - // Generate String() method on enum type. - void EnumStringer(const EnumDef &enum_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "func (v " + enum_def.name + ") String() string {\n"; - code += "\tif s, ok := EnumNames" + enum_def.name + "[v]; ok {\n"; - code += "\t\treturn s\n"; - code += "\t}\n"; - code += "\treturn \"" + enum_def.name; - code += "(\" + strconv.FormatInt(int64(v), 10) + \")\"\n"; - code += "}\n\n"; - } - - // Begin enum value map. - void BeginEnumValues(const EnumDef &enum_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "var EnumValues"; - code += enum_def.name; - code += " = map[string]" + GetEnumTypeName(enum_def) + "{\n"; - } - - // A single enum value member. - void EnumValueMember(const EnumDef &enum_def, const EnumVal &ev, - size_t max_name_length, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "\t\""; - code += ev.name; - code += "\": "; - code += std::string(max_name_length - ev.name.length(), ' '); - code += enum_def.name; - code += ev.name; - code += ",\n"; - } - - // End enum value map. - void EndEnumValues(std::string *code_ptr) { - std::string &code = *code_ptr; - code += "}\n\n"; - } - - // Initialize a new struct or table from existing data. - void NewRootTypeFromBuffer(const StructDef &struct_def, - std::string *code_ptr) { - std::string &code = *code_ptr; - std::string size_prefix[] = { "", "SizePrefixed" }; - - for (int i = 0; i < 2; i++) { - code += "func Get" + size_prefix[i] + "RootAs"; - code += struct_def.name; - code += "(buf []byte, offset flatbuffers.UOffsetT) "; - code += "*" + struct_def.name + ""; - code += " {\n"; - if (i == 0) { - code += "\tn := flatbuffers.GetUOffsetT(buf[offset:])\n"; - } else { - code += - "\tn := " - "flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])\n"; - } - code += "\tx := &" + struct_def.name + "{}\n"; - if (i == 0) { - code += "\tx.Init(buf, n+offset)\n"; - } else { - code += "\tx.Init(buf, n+offset+flatbuffers.SizeUint32)\n"; - } - code += "\treturn x\n"; - code += "}\n\n"; - } - } - - // Initialize an existing object with other data, to avoid an allocation. - void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - GenReceiver(struct_def, code_ptr); - code += " Init(buf []byte, i flatbuffers.UOffsetT) "; - code += "{\n"; - code += "\trcv._tab.Bytes = buf\n"; - code += "\trcv._tab.Pos = i\n"; - code += "}\n\n"; - } - - // Implement the table accessor - void GenTableAccessor(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - GenReceiver(struct_def, code_ptr); - code += " Table() flatbuffers.Table "; - code += "{\n"; - - if (struct_def.fixed) { - code += "\treturn rcv._tab.Table\n"; - } else { - code += "\treturn rcv._tab\n"; - } - code += "}\n\n"; - } - - // Get the length of a vector. - void GetVectorLen(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name) + "Length("; - code += ") int " + OffsetPrefix(field); - code += "\t\treturn rcv._tab.VectorLen(o)\n\t}\n"; - code += "\treturn 0\n}\n\n"; - } - - // Get a [ubyte] vector as a byte slice. - void GetUByteSlice(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name) + "Bytes("; - code += ") []byte " + OffsetPrefix(field); - code += "\t\treturn rcv._tab.ByteVector(o + rcv._tab.Pos)\n\t}\n"; - code += "\treturn nil\n}\n\n"; - } - - // Get the value of a struct's scalar. - void GetScalarFieldOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - std::string getter = GenGetter(field.value.type); - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name); - code += "() " + TypeName(field) + " {\n"; - code += "\treturn " + - CastToEnum(field.value.type, - getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" + - NumToString(field.value.offset) + "))"); - code += "\n}\n"; - } - - // Get the value of a table's scalar. - void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - std::string getter = GenGetter(field.value.type); - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name); - code += "() " + TypeName(field) + " "; - code += OffsetPrefix(field) + "\t\treturn "; - code += CastToEnum(field.value.type, getter + "(o + rcv._tab.Pos)"); - code += "\n\t}\n"; - code += "\treturn " + GenConstant(field) + "\n"; - code += "}\n\n"; - } - - // Get a struct by initializing an existing struct. - // Specific to Struct. - void GetStructFieldOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name); - code += "(obj *" + TypeName(field); - code += ") *" + TypeName(field); - code += " {\n"; - code += "\tif obj == nil {\n"; - code += "\t\tobj = new(" + TypeName(field) + ")\n"; - code += "\t}\n"; - code += "\tobj.Init(rcv._tab.Bytes, rcv._tab.Pos+"; - code += NumToString(field.value.offset) + ")"; - code += "\n\treturn obj\n"; - code += "}\n"; - } - - // Get a struct by initializing an existing struct. - // Specific to Table. - void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name); - code += "(obj *"; - code += TypeName(field); - code += ") *" + TypeName(field) + " " + OffsetPrefix(field); - if (field.value.type.struct_def->fixed) { - code += "\t\tx := o + rcv._tab.Pos\n"; - } else { - code += "\t\tx := rcv._tab.Indirect(o + rcv._tab.Pos)\n"; - } - code += "\t\tif obj == nil {\n"; - code += "\t\t\tobj = new(" + TypeName(field) + ")\n"; - code += "\t\t}\n"; - code += "\t\tobj.Init(rcv._tab.Bytes, x)\n"; - code += "\t\treturn obj\n\t}\n\treturn nil\n"; - code += "}\n\n"; - } - - // Get the value of a string. - void GetStringField(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name); - code += "() " + TypeName(field) + " "; - code += OffsetPrefix(field) + "\t\treturn " + GenGetter(field.value.type); - code += "(o + rcv._tab.Pos)\n\t}\n\treturn nil\n"; - code += "}\n\n"; - } - - // Get the value of a union from an object. - void GetUnionField(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name) + "("; - code += "obj " + GenTypePointer(field.value.type) + ") bool "; - code += OffsetPrefix(field); - code += "\t\t" + GenGetter(field.value.type); - code += "(obj, o)\n\t\treturn true\n\t}\n"; - code += "\treturn false\n"; - code += "}\n\n"; - } - - // Get the value of a vector's struct member. - void GetMemberOfVectorOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name); - code += "(obj *" + TypeName(field); - code += ", j int) bool " + OffsetPrefix(field); - code += "\t\tx := rcv._tab.Vector(o)\n"; - code += "\t\tx += flatbuffers.UOffsetT(j) * "; - code += NumToString(InlineSize(vectortype)) + "\n"; - if (!(vectortype.struct_def->fixed)) { - code += "\t\tx = rcv._tab.Indirect(x)\n"; - } - code += "\t\tobj.Init(rcv._tab.Bytes, x)\n"; - code += "\t\treturn true\n\t}\n"; - code += "\treturn false\n"; - code += "}\n\n"; - } - - // Get the value of a vector's non-struct member. - void GetMemberOfVectorOfNonStruct(const StructDef &struct_def, - const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - GenReceiver(struct_def, code_ptr); - code += " " + MakeCamel(field.name); - code += "(j int) " + TypeName(field) + " "; - code += OffsetPrefix(field); - code += "\t\ta := rcv._tab.Vector(o)\n"; - code += "\t\treturn " + - CastToEnum(field.value.type, - GenGetter(field.value.type) + - "(a + flatbuffers.UOffsetT(j*" + - NumToString(InlineSize(vectortype)) + "))"); - code += "\n\t}\n"; - if (IsString(vectortype)) { - code += "\treturn nil\n"; - } else if (vectortype.base_type == BASE_TYPE_BOOL) { - code += "\treturn false\n"; - } else { - code += "\treturn 0\n"; - } - code += "}\n\n"; - } - - // Begin the creator function signature. - void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - if (code.substr(code.length() - 2) != "\n\n") { - // a previous mutate has not put an extra new line - code += "\n"; - } - code += "func Create" + struct_def.name; - code += "(builder *flatbuffers.Builder"; - } - - // Recursively generate arguments for a constructor, to deal with nested - // structs. - void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix, - std::string *code_ptr) { - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (IsStruct(field.value.type)) { - // Generate arguments for a struct inside a struct. To ensure names - // don't clash, and to make it obvious these arguments are constructing - // a nested struct, prefix the name with the field name. - StructBuilderArgs(*field.value.type.struct_def, - (nameprefix + (field.name + "_")).c_str(), code_ptr); - } else { - std::string &code = *code_ptr; - code += std::string(", ") + nameprefix; - code += GoIdentity(field.name); - code += " " + TypeName(field); - } - } - } - - // End the creator function signature. - void EndBuilderArgs(std::string *code_ptr) { - std::string &code = *code_ptr; - code += ") flatbuffers.UOffsetT {\n"; - } - - // Recursively generate struct construction statements and instert manual - // padding. - void StructBuilderBody(const StructDef &struct_def, const char *nameprefix, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", "; - code += NumToString(struct_def.bytesize) + ")\n"; - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - if (field.padding) - code += "\tbuilder.Pad(" + NumToString(field.padding) + ")\n"; - if (IsStruct(field.value.type)) { - StructBuilderBody(*field.value.type.struct_def, - (nameprefix + (field.name + "_")).c_str(), code_ptr); - } else { - code += "\tbuilder.Prepend" + GenMethod(field) + "("; - code += CastToBaseType(field.value.type, - nameprefix + GoIdentity(field.name)) + - ")\n"; - } - } - } - - void EndBuilderBody(std::string *code_ptr) { - std::string &code = *code_ptr; - code += "\treturn builder.Offset()\n"; - code += "}\n"; - } - - // Get the value of a table's starting offset. - void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "func " + struct_def.name + "Start"; - code += "(builder *flatbuffers.Builder) {\n"; - code += "\tbuilder.StartObject("; - code += NumToString(struct_def.fields.vec.size()); - code += ")\n}\n"; - } - - // Set the value of a table's field. - void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field, - const size_t offset, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "func " + struct_def.name + "Add" + MakeCamel(field.name); - code += "(builder *flatbuffers.Builder, "; - code += GoIdentity(field.name) + " "; - if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) { - code += "flatbuffers.UOffsetT"; - } else { - code += TypeName(field); - } - code += ") {\n"; - code += "\tbuilder.Prepend"; - code += GenMethod(field) + "Slot("; - code += NumToString(offset) + ", "; - if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) { - code += "flatbuffers.UOffsetT"; - code += "("; - code += GoIdentity(field.name) + ")"; - } else { - code += CastToBaseType(field.value.type, GoIdentity(field.name)); - } - code += ", " + GenConstant(field); - code += ")\n}\n"; - } - - // Set the value of one of the members of a table's vector. - void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += "func " + struct_def.name + "Start"; - code += MakeCamel(field.name); - code += "Vector(builder *flatbuffers.Builder, numElems int) "; - code += "flatbuffers.UOffsetT {\n\treturn builder.StartVector("; - auto vector_type = field.value.type.VectorType(); - auto alignment = InlineAlignment(vector_type); - auto elem_size = InlineSize(vector_type); - code += NumToString(elem_size); - code += ", numElems, " + NumToString(alignment); - code += ")\n}\n"; - } - - // Get the offset of the end of a table. - void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "func " + struct_def.name + "End"; - code += "(builder *flatbuffers.Builder) flatbuffers.UOffsetT "; - code += "{\n\treturn builder.EndObject()\n}\n"; - } - - // Generate the receiver for function signatures. - void GenReceiver(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "func (rcv *" + struct_def.name + ")"; - } - - // Generate a struct field getter, conditioned on its child type(s). - void GenStructAccessor(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - GenComment(field.doc_comment, code_ptr, nullptr, ""); - if (IsScalar(field.value.type.base_type)) { - if (struct_def.fixed) { - GetScalarFieldOfStruct(struct_def, field, code_ptr); - } else { - GetScalarFieldOfTable(struct_def, field, code_ptr); - } - } else { - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: - if (struct_def.fixed) { - GetStructFieldOfStruct(struct_def, field, code_ptr); - } else { - GetStructFieldOfTable(struct_def, field, code_ptr); - } - break; - case BASE_TYPE_STRING: - GetStringField(struct_def, field, code_ptr); - break; - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - if (vectortype.base_type == BASE_TYPE_STRUCT) { - GetMemberOfVectorOfStruct(struct_def, field, code_ptr); - } else { - GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr); - } - break; - } - case BASE_TYPE_UNION: GetUnionField(struct_def, field, code_ptr); break; - default: FLATBUFFERS_ASSERT(0); - } - } - if (IsVector(field.value.type)) { - GetVectorLen(struct_def, field, code_ptr); - if (field.value.type.element == BASE_TYPE_UCHAR) { - GetUByteSlice(struct_def, field, code_ptr); - } - } - } - - // Mutate the value of a struct's scalar. - void MutateScalarFieldOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - std::string type = MakeCamel(GenTypeBasic(field.value.type)); - std::string setter = "rcv._tab.Mutate" + type; - GenReceiver(struct_def, code_ptr); - code += " Mutate" + MakeCamel(field.name); - code += "(n " + TypeName(field) + ") bool {\n\treturn " + setter; - code += "(rcv._tab.Pos+flatbuffers.UOffsetT("; - code += NumToString(field.value.offset) + "), "; - code += CastToBaseType(field.value.type, "n") + ")\n}\n\n"; - } - - // Mutate the value of a table's scalar. - void MutateScalarFieldOfTable(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - std::string type = MakeCamel(GenTypeBasic(field.value.type)); - std::string setter = "rcv._tab.Mutate" + type + "Slot"; - GenReceiver(struct_def, code_ptr); - code += " Mutate" + MakeCamel(field.name); - code += "(n " + TypeName(field) + ") bool {\n\treturn "; - code += setter + "(" + NumToString(field.value.offset) + ", "; - code += CastToBaseType(field.value.type, "n") + ")\n"; - code += "}\n\n"; - } - - // Mutate an element of a vector of scalars. - void MutateElementOfVectorOfNonStruct(const StructDef &struct_def, - const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - std::string type = MakeCamel(GenTypeBasic(vectortype)); - std::string setter = "rcv._tab.Mutate" + type; - GenReceiver(struct_def, code_ptr); - code += " Mutate" + MakeCamel(field.name); - code += "(j int, n " + TypeName(field) + ") bool "; - code += OffsetPrefix(field); - code += "\t\ta := rcv._tab.Vector(o)\n"; - code += "\t\treturn " + setter + "("; - code += "a+flatbuffers.UOffsetT(j*"; - code += NumToString(InlineSize(vectortype)) + "), "; - code += CastToBaseType(vectortype, "n") + ")\n"; - code += "\t}\n"; - code += "\treturn false\n"; - code += "}\n\n"; - } - - // Generate a struct field setter, conditioned on its child type(s). - void GenStructMutator(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - GenComment(field.doc_comment, code_ptr, nullptr, ""); - if (IsScalar(field.value.type.base_type)) { - if (struct_def.fixed) { - MutateScalarFieldOfStruct(struct_def, field, code_ptr); - } else { - MutateScalarFieldOfTable(struct_def, field, code_ptr); - } - } else if (IsVector(field.value.type)) { - if (IsScalar(field.value.type.element)) { - MutateElementOfVectorOfNonStruct(struct_def, field, code_ptr); - } - } - } - - // Generate table constructors, conditioned on its members' types. - void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) { - GetStartOfTable(struct_def, code_ptr); - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - auto offset = it - struct_def.fields.vec.begin(); - BuildFieldOfTable(struct_def, field, offset, code_ptr); - if (IsVector(field.value.type)) { - BuildVectorOfTable(struct_def, field, code_ptr); - } - } - - GetEndOffsetOnTable(struct_def, code_ptr); - } - - // Generate struct or table methods. - void GenStruct(const StructDef &struct_def, std::string *code_ptr) { - if (struct_def.generated) return; - - cur_name_space_ = struct_def.defined_namespace; - - GenComment(struct_def.doc_comment, code_ptr, nullptr); - if (parser_.opts.generate_object_based_api) { - GenNativeStruct(struct_def, code_ptr); - } - BeginClass(struct_def, code_ptr); - if (!struct_def.fixed) { - // Generate a special accessor for the table that has been declared as - // the root type. - NewRootTypeFromBuffer(struct_def, code_ptr); - } - // Generate the Init method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - InitializeExisting(struct_def, code_ptr); - // Generate _tab accessor - GenTableAccessor(struct_def, code_ptr); - - // Generate struct fields accessors - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - GenStructAccessor(struct_def, field, code_ptr); - GenStructMutator(struct_def, field, code_ptr); - } - - // Generate builders - if (struct_def.fixed) { - // create a struct constructor function - GenStructBuilder(struct_def, code_ptr); - } else { - // Create a set of functions that allow table construction. - GenTableBuilders(struct_def, code_ptr); - } - } - - void GenNativeStruct(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "type " + NativeName(struct_def) + " struct {\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const FieldDef &field = **it; - if (field.deprecated) continue; - if (IsScalar(field.value.type.base_type) && - field.value.type.enum_def != nullptr && - field.value.type.enum_def->is_union) - continue; - code += "\t" + MakeCamel(field.name) + " " + - NativeType(field.value.type) + "\n"; - } - code += "}\n\n"; - - if (!struct_def.fixed) { - GenNativeTablePack(struct_def, code_ptr); - GenNativeTableUnPack(struct_def, code_ptr); - } else { - GenNativeStructPack(struct_def, code_ptr); - GenNativeStructUnPack(struct_def, code_ptr); - } - } - - void GenNativeUnion(const EnumDef &enum_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "type " + NativeName(enum_def) + " struct {\n"; - code += "\tType " + enum_def.name + "\n"; - code += "\tValue interface{}\n"; - code += "}\n\n"; - } - - void GenNativeUnionPack(const EnumDef &enum_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "func (t *" + NativeName(enum_def) + - ") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n"; - code += "\tif t == nil {\n\t\treturn 0\n\t}\n"; - - code += "\tswitch t.Type {\n"; - for (auto it2 = enum_def.Vals().begin(); it2 != enum_def.Vals().end(); - ++it2) { - const EnumVal &ev = **it2; - if (ev.IsZero()) continue; - code += "\tcase " + enum_def.name + ev.name + ":\n"; - code += "\t\treturn t.Value.(" + NativeType(ev.union_type) + - ").Pack(builder)\n"; - } - code += "\t}\n"; - code += "\treturn 0\n"; - code += "}\n\n"; - } - - void GenNativeUnionUnPack(const EnumDef &enum_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "func (rcv " + enum_def.name + - ") UnPack(table flatbuffers.Table) *" + NativeName(enum_def) + - " {\n"; - code += "\tswitch rcv {\n"; - - for (auto it2 = enum_def.Vals().begin(); it2 != enum_def.Vals().end(); - ++it2) { - const EnumVal &ev = **it2; - if (ev.IsZero()) continue; - code += "\tcase " + enum_def.name + ev.name + ":\n"; - code += "\t\tx := " + ev.union_type.struct_def->name + "{_tab: table}\n"; - - code += "\t\treturn &" + - WrapInNameSpaceAndTrack(enum_def.defined_namespace, - NativeName(enum_def)) + - "{ Type: " + enum_def.name + ev.name + ", Value: x.UnPack() }\n"; - } - code += "\t}\n"; - code += "\treturn nil\n"; - code += "}\n\n"; - } - - void GenNativeTablePack(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "func (t *" + NativeName(struct_def) + - ") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n"; - code += "\tif t == nil { return 0 }\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const FieldDef &field = **it; - if (field.deprecated) continue; - if (IsScalar(field.value.type.base_type)) continue; - - std::string offset = MakeCamel(field.name, false) + "Offset"; - - if (IsString(field.value.type)) { - code += "\t" + offset + " := builder.CreateString(t." + - MakeCamel(field.name) + ")\n"; - } else if (IsVector(field.value.type) && - field.value.type.element == BASE_TYPE_UCHAR && - field.value.type.enum_def == nullptr) { - code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n"; - code += "\tif t." + MakeCamel(field.name) + " != nil {\n"; - code += "\t\t" + offset + " = builder.CreateByteString(t." + - MakeCamel(field.name) + ")\n"; - code += "\t}\n"; - } else if (IsVector(field.value.type)) { - code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n"; - code += "\tif t." + MakeCamel(field.name) + " != nil {\n"; - std::string length = MakeCamel(field.name, false) + "Length"; - std::string offsets = MakeCamel(field.name, false) + "Offsets"; - code += "\t\t" + length + " := len(t." + MakeCamel(field.name) + ")\n"; - if (field.value.type.element == BASE_TYPE_STRING) { - code += "\t\t" + offsets + " := make([]flatbuffers.UOffsetT, " + - length + ")\n"; - code += "\t\tfor j := 0; j < " + length + "; j++ {\n"; - code += "\t\t\t" + offsets + "[j] = builder.CreateString(t." + - MakeCamel(field.name) + "[j])\n"; - code += "\t\t}\n"; - } else if (field.value.type.element == BASE_TYPE_STRUCT && - !field.value.type.struct_def->fixed) { - code += "\t\t" + offsets + " := make([]flatbuffers.UOffsetT, " + - length + ")\n"; - code += "\t\tfor j := 0; j < " + length + "; j++ {\n"; - code += "\t\t\t" + offsets + "[j] = t." + MakeCamel(field.name) + - "[j].Pack(builder)\n"; - code += "\t\t}\n"; - } - code += "\t\t" + struct_def.name + "Start" + MakeCamel(field.name) + - "Vector(builder, " + length + ")\n"; - code += "\t\tfor j := " + length + " - 1; j >= 0; j-- {\n"; - if (IsScalar(field.value.type.element)) { - code += "\t\t\tbuilder.Prepend" + - MakeCamel(GenTypeBasic(field.value.type.VectorType())) + "(" + - CastToBaseType(field.value.type.VectorType(), - "t." + MakeCamel(field.name) + "[j]") + - ")\n"; - } else if (field.value.type.element == BASE_TYPE_STRUCT && - field.value.type.struct_def->fixed) { - code += "\t\t\tt." + MakeCamel(field.name) + "[j].Pack(builder)\n"; - } else { - code += "\t\t\tbuilder.PrependUOffsetT(" + offsets + "[j])\n"; - } - code += "\t\t}\n"; - code += "\t\t" + offset + " = builder.EndVector(" + length + ")\n"; - code += "\t}\n"; - } else if (field.value.type.base_type == BASE_TYPE_STRUCT) { - if (field.value.type.struct_def->fixed) continue; - code += "\t" + offset + " := t." + MakeCamel(field.name) + - ".Pack(builder)\n"; - } else if (field.value.type.base_type == BASE_TYPE_UNION) { - code += "\t" + offset + " := t." + MakeCamel(field.name) + - ".Pack(builder)\n"; - code += "\t\n"; - } else { - FLATBUFFERS_ASSERT(0); - } - } - code += "\t" + struct_def.name + "Start(builder)\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const FieldDef &field = **it; - if (field.deprecated) continue; - - std::string offset = MakeCamel(field.name, false) + "Offset"; - if (IsScalar(field.value.type.base_type)) { - if (field.value.type.enum_def == nullptr || - !field.value.type.enum_def->is_union) { - code += "\t" + struct_def.name + "Add" + MakeCamel(field.name) + - "(builder, t." + MakeCamel(field.name) + ")\n"; - } - } else { - if (field.value.type.base_type == BASE_TYPE_STRUCT && - field.value.type.struct_def->fixed) { - code += "\t" + offset + " := t." + MakeCamel(field.name) + - ".Pack(builder)\n"; - } else if (field.value.type.enum_def != nullptr && - field.value.type.enum_def->is_union) { - code += "\tif t." + MakeCamel(field.name) + " != nil {\n"; - code += "\t\t" + struct_def.name + "Add" + - MakeCamel(field.name + UnionTypeFieldSuffix()) + - "(builder, t." + MakeCamel(field.name) + ".Type)\n"; - code += "\t}\n"; - } - code += "\t" + struct_def.name + "Add" + MakeCamel(field.name) + - "(builder, " + offset + ")\n"; - } - } - code += "\treturn " + struct_def.name + "End(builder)\n"; - code += "}\n\n"; - } - - void GenNativeTableUnPack(const StructDef &struct_def, - std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" + - NativeName(struct_def) + ") {\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const FieldDef &field = **it; - if (field.deprecated) continue; - std::string field_name_camel = MakeCamel(field.name); - std::string length = MakeCamel(field.name, false) + "Length"; - if (IsScalar(field.value.type.base_type)) { - if (field.value.type.enum_def != nullptr && - field.value.type.enum_def->is_union) - continue; - code += - "\tt." + field_name_camel + " = rcv." + field_name_camel + "()\n"; - } else if (IsString(field.value.type)) { - code += "\tt." + field_name_camel + " = string(rcv." + - field_name_camel + "())\n"; - } else if (IsVector(field.value.type) && - field.value.type.element == BASE_TYPE_UCHAR && - field.value.type.enum_def == nullptr) { - code += "\tt." + field_name_camel + " = rcv." + field_name_camel + - "Bytes()\n"; - } else if (IsVector(field.value.type)) { - code += "\t" + length + " := rcv." + field_name_camel + "Length()\n"; - code += "\tt." + field_name_camel + " = make(" + - NativeType(field.value.type) + ", " + length + ")\n"; - code += "\tfor j := 0; j < " + length + "; j++ {\n"; - if (field.value.type.element == BASE_TYPE_STRUCT) { - code += "\t\tx := " + - WrapInNameSpaceAndTrack(*field.value.type.struct_def) + - "{}\n"; - code += "\t\trcv." + field_name_camel + "(&x, j)\n"; - } - code += "\t\tt." + field_name_camel + "[j] = "; - if (IsScalar(field.value.type.element)) { - code += "rcv." + field_name_camel + "(j)"; - } else if (field.value.type.element == BASE_TYPE_STRING) { - code += "string(rcv." + field_name_camel + "(j))"; - } else if (field.value.type.element == BASE_TYPE_STRUCT) { - code += "x.UnPack()"; - } else { - // TODO(iceboy): Support vector of unions. - FLATBUFFERS_ASSERT(0); - } - code += "\n"; - code += "\t}\n"; - } else if (field.value.type.base_type == BASE_TYPE_STRUCT) { - code += "\tt." + field_name_camel + " = rcv." + field_name_camel + - "(nil).UnPack()\n"; - } else if (field.value.type.base_type == BASE_TYPE_UNION) { - std::string field_table = MakeCamel(field.name, false) + "Table"; - code += "\t" + field_table + " := flatbuffers.Table{}\n"; - code += - "\tif rcv." + MakeCamel(field.name) + "(&" + field_table + ") {\n"; - code += "\t\tt." + field_name_camel + " = rcv." + - MakeCamel(field.name + UnionTypeFieldSuffix()) + "().UnPack(" + - field_table + ")\n"; - code += "\t}\n"; - } else { - FLATBUFFERS_ASSERT(0); - } - } - code += "}\n\n"; - - code += "func (rcv *" + struct_def.name + ") UnPack() *" + - NativeName(struct_def) + " {\n"; - code += "\tif rcv == nil { return nil }\n"; - code += "\tt := &" + NativeName(struct_def) + "{}\n"; - code += "\trcv.UnPackTo(t)\n"; - code += "\treturn t\n"; - code += "}\n\n"; - } - - void GenNativeStructPack(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "func (t *" + NativeName(struct_def) + - ") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n"; - code += "\tif t == nil { return 0 }\n"; - code += "\treturn Create" + struct_def.name + "(builder"; - StructPackArgs(struct_def, "", code_ptr); - code += ")\n"; - code += "}\n"; - } - - void StructPackArgs(const StructDef &struct_def, const char *nameprefix, - std::string *code_ptr) { - std::string &code = *code_ptr; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const FieldDef &field = **it; - if (field.value.type.base_type == BASE_TYPE_STRUCT) { - StructPackArgs(*field.value.type.struct_def, - (nameprefix + MakeCamel(field.name) + ".").c_str(), - code_ptr); - } else { - code += std::string(", t.") + nameprefix + MakeCamel(field.name); - } - } - } - - void GenNativeStructUnPack(const StructDef &struct_def, - std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" + - NativeName(struct_def) + ") {\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const FieldDef &field = **it; - if (field.value.type.base_type == BASE_TYPE_STRUCT) { - code += "\tt." + MakeCamel(field.name) + " = rcv." + - MakeCamel(field.name) + "(nil).UnPack()\n"; - } else { - code += "\tt." + MakeCamel(field.name) + " = rcv." + - MakeCamel(field.name) + "()\n"; - } - } - code += "}\n\n"; - - code += "func (rcv *" + struct_def.name + ") UnPack() *" + - NativeName(struct_def) + " {\n"; - code += "\tif rcv == nil { return nil }\n"; - code += "\tt := &" + NativeName(struct_def) + "{}\n"; - code += "\trcv.UnPackTo(t)\n"; - code += "\treturn t\n"; - code += "}\n\n"; - } - - // Generate enum declarations. - void GenEnum(const EnumDef &enum_def, std::string *code_ptr) { - if (enum_def.generated) return; - - auto max_name_length = MaxNameLength(enum_def); - cur_name_space_ = enum_def.defined_namespace; - - GenComment(enum_def.doc_comment, code_ptr, nullptr); - GenEnumType(enum_def, code_ptr); - BeginEnum(code_ptr); - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - const EnumVal &ev = **it; - GenComment(ev.doc_comment, code_ptr, nullptr, "\t"); - EnumMember(enum_def, ev, max_name_length, code_ptr); - } - EndEnum(code_ptr); - - BeginEnumNames(enum_def, code_ptr); - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - const EnumVal &ev = **it; - EnumNameMember(enum_def, ev, max_name_length, code_ptr); - } - EndEnumNames(code_ptr); - - BeginEnumValues(enum_def, code_ptr); - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - EnumValueMember(enum_def, ev, max_name_length, code_ptr); - } - EndEnumValues(code_ptr); - - EnumStringer(enum_def, code_ptr); - } - - // Returns the function name that is able to read a value of the given type. - std::string GenGetter(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_STRING: return "rcv._tab.ByteVector"; - case BASE_TYPE_UNION: return "rcv._tab.Union"; - case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); - default: return "rcv._tab.Get" + MakeCamel(GenTypeBasic(type)); - } - } - - // Returns the method name for use with add/put calls. - std::string GenMethod(const FieldDef &field) { - return IsScalar(field.value.type.base_type) - ? MakeCamel(GenTypeBasic(field.value.type)) - : (IsStruct(field.value.type) ? "Struct" : "UOffsetT"); - } - - std::string GenTypeBasic(const Type &type) { - // clang-format off - static const char *ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, ...) \ - #GTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - return ctypename[type.base_type]; - } - - std::string GenTypePointer(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_STRING: return "[]byte"; - case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); - case BASE_TYPE_STRUCT: return WrapInNameSpaceAndTrack(*type.struct_def); - case BASE_TYPE_UNION: - // fall through - default: return "*flatbuffers.Table"; - } - } - - std::string GenTypeGet(const Type &type) { - if (type.enum_def != nullptr) { return GetEnumTypeName(*type.enum_def); } - return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type); - } - - std::string TypeName(const FieldDef &field) { - return GenTypeGet(field.value.type); - } - - // If type is an enum, returns value with a cast to the enum type, otherwise - // returns value as-is. - std::string CastToEnum(const Type &type, std::string value) { - if (type.enum_def == nullptr) { - return value; - } else { - return GenTypeGet(type) + "(" + value + ")"; - } - } - - // If type is an enum, returns value with a cast to the enum base type, - // otherwise returns value as-is. - std::string CastToBaseType(const Type &type, std::string value) { - if (type.enum_def == nullptr) { - return value; - } else { - return GenTypeBasic(type) + "(" + value + ")"; - } - } - - std::string GenConstant(const FieldDef &field) { - switch (field.value.type.base_type) { - case BASE_TYPE_BOOL: - return field.value.constant == "0" ? "false" : "true"; - default: return field.value.constant; - } - } - - std::string NativeName(const StructDef &struct_def) { - return parser_.opts.object_prefix + struct_def.name + - parser_.opts.object_suffix; - } - - std::string NativeName(const EnumDef &enum_def) { - return parser_.opts.object_prefix + enum_def.name + - parser_.opts.object_suffix; - } - - std::string NativeType(const Type &type) { - if (IsScalar(type.base_type)) { - if (type.enum_def == nullptr) { - return GenTypeBasic(type); - } else { - return GetEnumTypeName(*type.enum_def); - } - } else if (IsString(type)) { - return "string"; - } else if (IsVector(type)) { - return "[]" + NativeType(type.VectorType()); - } else if (type.base_type == BASE_TYPE_STRUCT) { - return "*" + WrapInNameSpaceAndTrack(type.struct_def->defined_namespace, - NativeName(*type.struct_def)); - } else if (type.base_type == BASE_TYPE_UNION) { - return "*" + WrapInNameSpaceAndTrack(type.enum_def->defined_namespace, - NativeName(*type.enum_def)); - } - FLATBUFFERS_ASSERT(0); - return std::string(); - } - - // Create a struct with a builder and the struct's arguments. - void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) { - BeginBuilderArgs(struct_def, code_ptr); - StructBuilderArgs(struct_def, "", code_ptr); - EndBuilderArgs(code_ptr); - - StructBuilderBody(struct_def, "", code_ptr); - EndBuilderBody(code_ptr); - } - // Begin by declaring namespace and imports. - void BeginFile(const std::string &name_space_name, const bool needs_imports, - const bool is_enum, std::string *code_ptr) { - std::string &code = *code_ptr; - code = code + - "// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n"; - code += "package " + name_space_name + "\n\n"; - if (needs_imports) { - code += "import (\n"; - if (is_enum) { code += "\t\"strconv\"\n\n"; } - if (!parser_.opts.go_import.empty()) { - code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n"; - } else { - code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n"; - } - if (tracked_imported_namespaces_.size() > 0) { - code += "\n"; - for (auto it = tracked_imported_namespaces_.begin(); - it != tracked_imported_namespaces_.end(); ++it) { - code += "\t" + NamespaceImportName(*it) + " \"" + - NamespaceImportPath(*it) + "\"\n"; - } - } - code += ")\n\n"; - } else { - if (is_enum) { code += "import \"strconv\"\n\n"; } - } - } - - // Save out the generated code for a Go Table type. - bool SaveType(const Definition &def, const std::string &classcode, - const bool needs_imports, const bool is_enum) { - if (!classcode.length()) return true; - - Namespace &ns = go_namespace_.components.empty() ? *def.defined_namespace - : go_namespace_; - std::string code = ""; - BeginFile(LastNamespacePart(ns), needs_imports, is_enum, &code); - code += classcode; - // Strip extra newlines at end of file to make it gofmt-clean. - while (code.length() > 2 && code.substr(code.length() - 2) == "\n\n") { - code.pop_back(); - } - std::string filename = NamespaceDir(ns) + def.name + ".go"; - return SaveFile(filename.c_str(), code, false); - } - - // Create the full name of the imported namespace (format: A__B__C). - std::string NamespaceImportName(const Namespace *ns) { - std::string s = ""; - for (auto it = ns->components.begin(); it != ns->components.end(); ++it) { - if (s.size() == 0) { - s += *it; - } else { - s += "__" + *it; - } - } - return s; - } - - // Create the full path for the imported namespace (format: A/B/C). - std::string NamespaceImportPath(const Namespace *ns) { - std::string s = ""; - for (auto it = ns->components.begin(); it != ns->components.end(); ++it) { - if (s.size() == 0) { - s += *it; - } else { - s += "/" + *it; - } - } - return s; - } - - // Ensure that a type is prefixed with its go package import name if it is - // used outside of its namespace. - std::string WrapInNameSpaceAndTrack(const Namespace *ns, - const std::string &name) { - if (CurrentNameSpace() == ns) return name; - - tracked_imported_namespaces_.insert(ns); - - std::string import_name = NamespaceImportName(ns); - return import_name + "." + name; - } - - std::string WrapInNameSpaceAndTrack(const Definition &def) { - return WrapInNameSpaceAndTrack(def.defined_namespace, def.name); - } - - const Namespace *CurrentNameSpace() const { return cur_name_space_; } - - static size_t MaxNameLength(const EnumDef &enum_def) { - size_t max = 0; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - max = std::max((*it)->name.length(), max); - } - return max; - } -}; -} // namespace go - -bool GenerateGo(const Parser &parser, const std::string &path, - const std::string &file_name) { - go::GoGenerator generator(parser, path, file_name, parser.opts.go_namespace); - return generator.generate(); -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_grpc.cpp b/contrib/libs/flatbuffers/src/idl_gen_grpc.cpp deleted file mode 100644 index 9aea745d4e..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_grpc.cpp +++ /dev/null @@ -1,557 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" -#include "src/compiler/cpp_generator.h" -#include "src/compiler/go_generator.h" -#include "src/compiler/java_generator.h" -#include "src/compiler/python_generator.h" -#include "src/compiler/swift_generator.h" -#include "src/compiler/ts_generator.h" - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4512) // C4512: 'class' : assignment operator could -// not be generated -#endif - -namespace flatbuffers { - -class FlatBufMethod : public grpc_generator::Method { - public: - enum Streaming { kNone, kClient, kServer, kBiDi }; - - FlatBufMethod(const RPCCall *method) : method_(method) { - streaming_ = kNone; - auto val = method_->attributes.Lookup("streaming"); - if (val) { - if (val->constant == "client") streaming_ = kClient; - if (val->constant == "server") streaming_ = kServer; - if (val->constant == "bidi") streaming_ = kBiDi; - } - } - - grpc::string GetLeadingComments(const grpc::string) const { return ""; } - - grpc::string GetTrailingComments(const grpc::string) const { return ""; } - - std::vector<grpc::string> GetAllComments() const { - return method_->doc_comment; - } - - std::string name() const { return method_->name; } - - // TODO: This method need to incorporate namespace for C++ side. Other - // language bindings simply don't use this method. - std::string GRPCType(const StructDef &sd) const { - return "flatbuffers::grpc::Message<" + sd.name + ">"; - } - - std::vector<std::string> get_input_namespace_parts() const { - return (*method_->request).defined_namespace->components; - } - - std::string get_input_type_name() const { return (*method_->request).name; } - - std::vector<std::string> get_output_namespace_parts() const { - return (*method_->response).defined_namespace->components; - } - - std::string get_output_type_name() const { return (*method_->response).name; } - - bool get_module_and_message_path_input(grpc::string * /*str*/, - grpc::string /*generator_file_name*/, - bool /*generate_in_pb2_grpc*/, - grpc::string /*import_prefix*/) const { - return true; - } - - bool get_module_and_message_path_output( - grpc::string * /*str*/, grpc::string /*generator_file_name*/, - bool /*generate_in_pb2_grpc*/, grpc::string /*import_prefix*/) const { - return true; - } - - std::string get_fb_builder() const { return "builder"; } - - std::string input_type_name() const { return GRPCType(*method_->request); } - - std::string output_type_name() const { return GRPCType(*method_->response); } - - bool NoStreaming() const { return streaming_ == kNone; } - - bool ClientStreaming() const { return streaming_ == kClient; } - - bool ServerStreaming() const { return streaming_ == kServer; } - - bool BidiStreaming() const { return streaming_ == kBiDi; } - - private: - const RPCCall *method_; - Streaming streaming_; -}; - -class FlatBufService : public grpc_generator::Service { - public: - FlatBufService(const ServiceDef *service) : service_(service) {} - - grpc::string GetLeadingComments(const grpc::string) const { return ""; } - - grpc::string GetTrailingComments(const grpc::string) const { return ""; } - - std::vector<grpc::string> GetAllComments() const { - return service_->doc_comment; - } - - std::vector<grpc::string> namespace_parts() const { - return service_->defined_namespace->components; - } - - std::string name() const { return service_->name; } - bool is_internal() const { - return service_->Definition::attributes.Lookup("private") ? true : false; - } - - int method_count() const { - return static_cast<int>(service_->calls.vec.size()); - } - - std::unique_ptr<const grpc_generator::Method> method(int i) const { - return std::unique_ptr<const grpc_generator::Method>( - new FlatBufMethod(service_->calls.vec[i])); - } - - private: - const ServiceDef *service_; -}; - -class FlatBufPrinter : public grpc_generator::Printer { - public: - FlatBufPrinter(std::string *str, const char indentation_type) - : str_(str), - escape_char_('$'), - indent_(0), - indentation_size_(2), - indentation_type_(indentation_type) {} - - void Print(const std::map<std::string, std::string> &vars, - const char *string_template) { - std::string s = string_template; - // Replace any occurrences of strings in "vars" that are surrounded - // by the escape character by what they're mapped to. - size_t pos; - while ((pos = s.find(escape_char_)) != std::string::npos) { - // Found an escape char, must also find the closing one. - size_t pos2 = s.find(escape_char_, pos + 1); - // If placeholder not closed, ignore. - if (pos2 == std::string::npos) break; - auto it = vars.find(s.substr(pos + 1, pos2 - pos - 1)); - // If unknown placeholder, ignore. - if (it == vars.end()) break; - // Subtitute placeholder. - s.replace(pos, pos2 - pos + 1, it->second); - } - Print(s.c_str()); - } - - void Print(const char *s) { - if (s == nullptr || *s == '\0') { return; } - // Add this string, but for each part separated by \n, add indentation. - for (;;) { - // Current indentation. - str_->insert(str_->end(), indent_ * indentation_size_, indentation_type_); - // See if this contains more than one line. - const char *lf = strchr(s, '\n'); - if (lf) { - (*str_) += std::string(s, lf + 1); - s = lf + 1; - if (!*s) break; // Only continue if there's more lines. - } else { - (*str_) += s; - break; - } - } - } - - void SetIndentationSize(const int size) { - FLATBUFFERS_ASSERT(str_->empty()); - indentation_size_ = size; - } - - void Indent() { indent_++; } - - void Outdent() { - indent_--; - FLATBUFFERS_ASSERT(indent_ >= 0); - } - - private: - std::string *str_; - char escape_char_; - int indent_; - int indentation_size_; - char indentation_type_; -}; - -class FlatBufFile : public grpc_generator::File { - public: - enum Language { - kLanguageGo, - kLanguageCpp, - kLanguageJava, - kLanguagePython, - kLanguageSwift, - kLanguageTS - }; - - FlatBufFile(const Parser &parser, const std::string &file_name, - Language language) - : parser_(parser), file_name_(file_name), language_(language) {} - - FlatBufFile &operator=(const FlatBufFile &); - - grpc::string GetLeadingComments(const grpc::string) const { return ""; } - - grpc::string GetTrailingComments(const grpc::string) const { return ""; } - - std::vector<grpc::string> GetAllComments() const { - return std::vector<grpc::string>(); - } - - std::string filename() const { return file_name_; } - - std::string filename_without_ext() const { - return StripExtension(file_name_); - } - - std::string message_header_ext() const { return "_generated.h"; } - - std::string service_header_ext() const { return ".grpc.fb.h"; } - - std::string package() const { - return parser_.current_namespace_->GetFullyQualifiedName(""); - } - - std::vector<std::string> package_parts() const { - return parser_.current_namespace_->components; - } - - std::string additional_headers() const { - switch (language_) { - case kLanguageCpp: { - return "#include \"flatbuffers/grpc.h\"\n"; - } - case kLanguageGo: { - return "import \"github.com/google/flatbuffers/go\""; - } - case kLanguageJava: { - return "import com.google.flatbuffers.grpc.FlatbuffersUtils;"; - } - case kLanguagePython: { - return ""; - } - case kLanguageSwift: { - return ""; - } - case kLanguageTS: { - return ""; - } - } - return ""; - } - - int service_count() const { - return static_cast<int>(parser_.services_.vec.size()); - } - - std::unique_ptr<const grpc_generator::Service> service(int i) const { - return std::unique_ptr<const grpc_generator::Service>( - new FlatBufService(parser_.services_.vec[i])); - } - - std::unique_ptr<grpc_generator::Printer> CreatePrinter( - std::string *str, const char indentation_type = ' ') const { - return std::unique_ptr<grpc_generator::Printer>( - new FlatBufPrinter(str, indentation_type)); - } - - private: - const Parser &parser_; - const std::string &file_name_; - const Language language_; -}; - -class GoGRPCGenerator : public flatbuffers::BaseGenerator { - public: - GoGRPCGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", "" /*Unused*/, "go"), - parser_(parser), - path_(path), - file_name_(file_name) {} - - bool generate() { - FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageGo); - grpc_go_generator::Parameters p; - p.custom_method_io_type = "flatbuffers.Builder"; - for (int i = 0; i < file.service_count(); i++) { - auto service = file.service(i); - const Definition *def = parser_.services_.vec[i]; - p.package_name = LastNamespacePart(*(def->defined_namespace)); - p.service_prefix = - def->defined_namespace->GetFullyQualifiedName(""); // file.package(); - std::string output = - grpc_go_generator::GenerateServiceSource(&file, service.get(), &p); - std::string filename = - NamespaceDir(*def->defined_namespace) + def->name + "_grpc.go"; - if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false; - } - return true; - } - - protected: - const Parser &parser_; - const std::string &path_, &file_name_; -}; - -bool GenerateGoGRPC(const Parser &parser, const std::string &path, - const std::string &file_name) { - int nservices = 0; - for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); - ++it) { - if (!(*it)->generated) nservices++; - } - if (!nservices) return true; - return GoGRPCGenerator(parser, path, file_name).generate(); -} - -bool GenerateCppGRPC(const Parser &parser, const std::string &path, - const std::string &file_name) { - int nservices = 0; - for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); - ++it) { - if (!(*it)->generated) nservices++; - } - if (!nservices) return true; - - grpc_cpp_generator::Parameters generator_parameters; - // TODO(wvo): make the other parameters in this struct configurable. - generator_parameters.use_system_headers = true; - - FlatBufFile fbfile(parser, file_name, FlatBufFile::kLanguageCpp); - - std::string header_code = - grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) + - grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) + - grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) + - grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters); - - std::string source_code = - grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) + - grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) + - grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) + - grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters); - - return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(), - header_code, false) && - flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(), - source_code, false); -} - -class JavaGRPCGenerator : public flatbuffers::BaseGenerator { - public: - JavaGRPCGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", "." /*separator*/, "java") {} - - bool generate() { - FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageJava); - grpc_java_generator::Parameters p; - for (int i = 0; i < file.service_count(); i++) { - auto service = file.service(i); - const Definition *def = parser_.services_.vec[i]; - p.package_name = - def->defined_namespace->GetFullyQualifiedName(""); // file.package(); - std::string output = - grpc_java_generator::GenerateServiceSource(&file, service.get(), &p); - std::string filename = - NamespaceDir(*def->defined_namespace) + def->name + "Grpc.java"; - if (!flatbuffers::SaveFile(filename.c_str(), output, false)) return false; - } - return true; - } -}; - -bool GenerateJavaGRPC(const Parser &parser, const std::string &path, - const std::string &file_name) { - int nservices = 0; - for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); - ++it) { - if (!(*it)->generated) nservices++; - } - if (!nservices) return true; - return JavaGRPCGenerator(parser, path, file_name).generate(); -} - -class PythonGRPCGenerator : public flatbuffers::BaseGenerator { - private: - CodeWriter code_; - - public: - PythonGRPCGenerator(const Parser &parser, const std::string &filename) - : BaseGenerator(parser, "", filename, "", "" /*Unused*/, "swift") {} - - bool generate() { - code_.Clear(); - code_ += - "# Generated by the gRPC Python protocol compiler plugin. " - "DO NOT EDIT!\n"; - code_ += "import grpc\n"; - - FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguagePython); - - for (int i = 0; i < file.service_count(); i++) { - auto service = file.service(i); - code_ += grpc_python_generator::Generate(&file, service.get()); - } - const auto final_code = code_.ToString(); - const auto filename = GenerateFileName(); - return SaveFile(filename.c_str(), final_code, false); - } - - std::string GenerateFileName() { - std::string namespace_dir; - auto &namespaces = parser_.namespaces_.back()->components; - for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { - if (it != namespaces.begin()) namespace_dir += kPathSeparator; - namespace_dir += *it; - } - std::string grpc_py_filename = namespace_dir; - if (!namespace_dir.empty()) grpc_py_filename += kPathSeparator; - return grpc_py_filename + file_name_ + "_grpc_fb.py"; - } -}; - -bool GeneratePythonGRPC(const Parser &parser, const std::string & /*path*/, - const std::string &file_name) { - int nservices = 0; - for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); - ++it) { - if (!(*it)->generated) nservices++; - } - if (!nservices) return true; - - return PythonGRPCGenerator(parser, file_name).generate(); -} - -class SwiftGRPCGenerator : public flatbuffers::BaseGenerator { - private: - CodeWriter code_; - - public: - SwiftGRPCGenerator(const Parser &parser, const std::string &path, - const std::string &filename) - : BaseGenerator(parser, path, filename, "", "" /*Unused*/, "swift") {} - - bool generate() { - code_.Clear(); - code_ += "// Generated GRPC code for FlatBuffers swift!"; - code_ += grpc_swift_generator::GenerateHeader(); - FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageSwift); - for (int i = 0; i < file.service_count(); i++) { - auto service = file.service(i); - code_ += grpc_swift_generator::Generate(&file, service.get()); - } - const auto final_code = code_.ToString(); - const auto filename = GeneratedFileName(path_, file_name_); - return SaveFile(filename.c_str(), final_code, false); - } - - static std::string GeneratedFileName(const std::string &path, - const std::string &file_name) { - return path + file_name + ".grpc.swift"; - } -}; - -bool GenerateSwiftGRPC(const Parser &parser, const std::string &path, - const std::string &file_name) { - int nservices = 0; - for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); - ++it) { - if (!(*it)->generated) nservices++; - } - if (!nservices) return true; - return SwiftGRPCGenerator(parser, path, file_name).generate(); -} - -class TSGRPCGenerator : public flatbuffers::BaseGenerator { - private: - CodeWriter code_; - - public: - TSGRPCGenerator(const Parser &parser, const std::string &path, - const std::string &filename) - : BaseGenerator(parser, path, filename, "", "" /*Unused*/, "ts") {} - - bool generate() { - code_.Clear(); - FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageTS); - - for (int i = 0; i < file.service_count(); i++) { - auto service = file.service(i); - code_ += grpc_ts_generator::Generate(&file, service.get(), file_name_); - const auto ts_name = GeneratedFileName(path_, file_name_); - if (!SaveFile(ts_name.c_str(), code_.ToString(), false)) return false; - - code_.Clear(); - code_ += grpc_ts_generator::GenerateInterface(&file, service.get(), - file_name_); - const auto ts_interface_name = GeneratedFileName(path_, file_name_, true); - if (!SaveFile(ts_interface_name.c_str(), code_.ToString(), false)) - return false; - } - return true; - } - - static std::string GeneratedFileName(const std::string &path, - const std::string &file_name, - const bool is_interface = false) { - if (is_interface) return path + file_name + "_grpc.d.ts"; - return path + file_name + "_grpc.js"; - } -}; - -bool GenerateTSGRPC(const Parser &parser, const std::string &path, - const std::string &file_name) { - int nservices = 0; - for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end(); - ++it) { - if (!(*it)->generated) nservices++; - } - if (!nservices) return true; - return TSGRPCGenerator(parser, path, file_name).generate(); -} - -} // namespace flatbuffers - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif diff --git a/contrib/libs/flatbuffers/src/idl_gen_java.cpp b/contrib/libs/flatbuffers/src/idl_gen_java.cpp deleted file mode 100644 index cfd3a55cdb..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_java.cpp +++ /dev/null @@ -1,1244 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -#if defined(FLATBUFFERS_CPP98_STL) -# include <cctype> -#endif // defined(FLATBUFFERS_CPP98_STL) - -namespace flatbuffers { -namespace java { - -static TypedFloatConstantGenerator JavaFloatGen("Double.", "Float.", "NaN", - "POSITIVE_INFINITY", - "NEGATIVE_INFINITY"); - -static CommentConfig comment_config = { - "/**", - " *", - " */", -}; - -class JavaGenerator : public BaseGenerator { - public: - JavaGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", ".", "java"), - cur_name_space_(nullptr) {} - - JavaGenerator &operator=(const JavaGenerator &); - bool generate() { - std::string one_file_code; - cur_name_space_ = parser_.current_namespace_; - - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - std::string enumcode; - auto &enum_def = **it; - if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace; - GenEnum(enum_def, &enumcode); - if (parser_.opts.one_file) { - one_file_code += enumcode; - } else { - if (!SaveType(enum_def.name, *enum_def.defined_namespace, enumcode, - /* needs_includes= */ false)) - return false; - } - } - - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - std::string declcode; - auto &struct_def = **it; - if (!parser_.opts.one_file) - cur_name_space_ = struct_def.defined_namespace; - GenStruct(struct_def, &declcode); - if (parser_.opts.one_file) { - one_file_code += declcode; - } else { - if (!SaveType(struct_def.name, *struct_def.defined_namespace, declcode, - /* needs_includes= */ true)) - return false; - } - } - - if (parser_.opts.one_file) { - return SaveType(file_name_, *parser_.current_namespace_, one_file_code, - /* needs_includes= */ true); - } - return true; - } - - // Save out the generated code for a single class while adding - // declaration boilerplate. - bool SaveType(const std::string &defname, const Namespace &ns, - const std::string &classcode, bool needs_includes) const { - if (!classcode.length()) return true; - - std::string code; - code = "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; - - std::string namespace_name = FullNamespace(".", ns); - if (!namespace_name.empty()) { - code += "package " + namespace_name + ";"; - code += "\n\n"; - } - if (needs_includes) { - code += - "import java.nio.*;\nimport java.lang.*;\nimport " - "java.util.*;\nimport com.google.flatbuffers.*;\n"; - if (parser_.opts.gen_nullable) { - code += "\nimport javax.annotation.Nullable;\n"; - } - if (parser_.opts.java_checkerframework) { - code += "\nimport org.checkerframework.dataflow.qual.Pure;\n"; - } - code += "\n"; - } - - code += classcode; - if (!namespace_name.empty()) code += ""; - auto filename = NamespaceDir(ns) + defname + ".java"; - return SaveFile(filename.c_str(), code, false); - } - - const Namespace *CurrentNameSpace() const { return cur_name_space_; } - - std::string GenNullableAnnotation(const Type &t) const { - return parser_.opts.gen_nullable && - !IsScalar(DestinationType(t, true).base_type) && - t.base_type != BASE_TYPE_VECTOR - ? " @Nullable " - : ""; - } - - std::string GenPureAnnotation(const Type &t) const { - return parser_.opts.java_checkerframework && - !IsScalar(DestinationType(t, true).base_type) - ? " @Pure " - : ""; - } - - std::string GenTypeBasic(const Type &type) const { - // clang-format off - static const char * const java_typename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, ...) \ - #JTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - return java_typename[type.base_type]; - } - - std::string GenTypePointer(const Type &type) const { - switch (type.base_type) { - case BASE_TYPE_STRING: return "String"; - case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); - case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def); - case BASE_TYPE_UNION: FLATBUFFERS_FALLTHROUGH(); // else fall thru - default: return "Table"; - } - } - - std::string GenTypeGet(const Type &type) const { - return IsScalar(type.base_type) - ? GenTypeBasic(type) - : (IsArray(type) ? GenTypeGet(type.VectorType()) - : GenTypePointer(type)); - } - - // Find the destination type the user wants to receive the value in (e.g. - // one size higher signed types for unsigned serialized values in Java). - Type DestinationType(const Type &type, bool vectorelem) const { - switch (type.base_type) { - // We use int for both uchar/ushort, since that generally means less - // casting than using short for uchar. - case BASE_TYPE_UCHAR: return Type(BASE_TYPE_INT); - case BASE_TYPE_USHORT: return Type(BASE_TYPE_INT); - case BASE_TYPE_UINT: return Type(BASE_TYPE_LONG); - case BASE_TYPE_ARRAY: - case BASE_TYPE_VECTOR: - if (vectorelem) return DestinationType(type.VectorType(), vectorelem); - FLATBUFFERS_FALLTHROUGH(); // else fall thru - default: return type; - } - } - - std::string GenOffsetType() const { return "int"; } - - std::string GenOffsetConstruct(const std::string &variable_name) const { - return variable_name; - } - - std::string GenVectorOffsetType() const { return "int"; } - - // Generate destination type name - std::string GenTypeNameDest(const Type &type) const { - return GenTypeGet(DestinationType(type, true)); - } - - // Mask to turn serialized value into destination type value. - std::string DestinationMask(const Type &type, bool vectorelem) const { - switch (type.base_type) { - case BASE_TYPE_UCHAR: return " & 0xFF"; - case BASE_TYPE_USHORT: return " & 0xFFFF"; - case BASE_TYPE_UINT: return " & 0xFFFFFFFFL"; - case BASE_TYPE_VECTOR: - if (vectorelem) return DestinationMask(type.VectorType(), vectorelem); - FLATBUFFERS_FALLTHROUGH(); // else fall thru - default: return ""; - } - } - - // Casts necessary to correctly read serialized data - std::string DestinationCast(const Type &type) const { - if (IsSeries(type)) { - return DestinationCast(type.VectorType()); - } else { - // Cast necessary to correctly read serialized unsigned values. - if (type.base_type == BASE_TYPE_UINT) return "(long)"; - } - return ""; - } - - // Cast statements for mutator method parameters. - // In Java, parameters representing unsigned numbers need to be cast down to - // their respective type. For example, a long holding an unsigned int value - // would be cast down to int before being put onto the buffer. - std::string SourceCast(const Type &type, bool castFromDest) const { - if (IsSeries(type)) { - return SourceCast(type.VectorType(), castFromDest); - } else { - if (castFromDest) { - if (type.base_type == BASE_TYPE_UINT) - return "(int)"; - else if (type.base_type == BASE_TYPE_USHORT) - return "(short)"; - else if (type.base_type == BASE_TYPE_UCHAR) - return "(byte)"; - } - } - return ""; - } - - std::string SourceCast(const Type &type) const { - return SourceCast(type, true); - } - - std::string SourceCastBasic(const Type &type, bool castFromDest) const { - return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : ""; - } - - std::string SourceCastBasic(const Type &type) const { - return SourceCastBasic(type, true); - } - - std::string GenEnumDefaultValue(const FieldDef &field) const { - auto &value = field.value; - FLATBUFFERS_ASSERT(value.type.enum_def); - auto &enum_def = *value.type.enum_def; - auto enum_val = enum_def.FindByValue(value.constant); - return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name) - : value.constant; - } - - std::string GenDefaultValue(const FieldDef &field) const { - auto &value = field.value; - auto constant = field.IsScalarOptional() ? "0" : value.constant; - auto longSuffix = "L"; - switch (value.type.base_type) { - case BASE_TYPE_BOOL: return constant == "0" ? "false" : "true"; - case BASE_TYPE_ULONG: { - // Converts the ulong into its bits signed equivalent - uint64_t defaultValue = StringToUInt(constant.c_str()); - return NumToString(static_cast<int64_t>(defaultValue)) + longSuffix; - } - case BASE_TYPE_UINT: - case BASE_TYPE_LONG: return constant + longSuffix; - default: - if (IsFloat(value.type.base_type)) { - if (field.IsScalarOptional()) { - return value.type.base_type == BASE_TYPE_DOUBLE ? "0.0" : "0f"; - } - return JavaFloatGen.GenFloatConstant(field); - } else { - return constant; - } - } - } - - std::string GenDefaultValueBasic(const FieldDef &field) const { - auto &value = field.value; - if (!IsScalar(value.type.base_type)) { return "0"; } - return GenDefaultValue(field); - } - - void GenEnum(EnumDef &enum_def, std::string *code_ptr) const { - std::string &code = *code_ptr; - if (enum_def.generated) return; - - // Generate enum definitions of the form: - // public static (final) int name = value; - // In Java, we use ints rather than the Enum feature, because we want them - // to map directly to how they're used in C/C++ and file formats. - // That, and Java Enums are expensive, and not universally liked. - GenComment(enum_def.doc_comment, code_ptr, &comment_config); - - if (enum_def.attributes.Lookup("private")) { - // For Java, we leave the enum unmarked to indicate package-private - } else { - code += "public "; - } - code += "final class " + enum_def.name; - code += " {\n"; - code += " private " + enum_def.name + "() { }\n"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - GenComment(ev.doc_comment, code_ptr, &comment_config, " "); - code += " public static final "; - code += GenTypeBasic(DestinationType(enum_def.underlying_type, false)); - code += " "; - code += ev.name + " = "; - code += enum_def.ToString(ev); - code += ";\n"; - } - - // Generate a generate string table for enum values. - // Problem is, if values are very sparse that could generate really big - // tables. Ideally in that case we generate a map lookup instead, but for - // the moment we simply don't output a table at all. - auto range = enum_def.Distance(); - // Average distance between values above which we consider a table - // "too sparse". Change at will. - static const uint64_t kMaxSparseness = 5; - if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) { - code += "\n public static final String"; - code += "[] names = { "; - auto val = enum_def.Vals().front(); - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - auto ev = *it; - for (auto k = enum_def.Distance(val, ev); k > 1; --k) code += "\"\", "; - val = ev; - code += "\"" + (*it)->name + "\", "; - } - code += "};\n\n"; - code += " public static "; - code += "String"; - code += " " + MakeCamel("name", false); - code += "(int e) { return names[e"; - if (enum_def.MinValue()->IsNonZero()) - code += " - " + enum_def.MinValue()->name; - code += "]; }\n"; - } - - // Close the class - code += "}\n\n"; - } - - // Returns the function name that is able to read a value of the given type. - std::string GenGetter(const Type &type) const { - switch (type.base_type) { - case BASE_TYPE_STRING: return "__string"; - case BASE_TYPE_STRUCT: return "__struct"; - case BASE_TYPE_UNION: return "__union"; - case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); - case BASE_TYPE_ARRAY: return GenGetter(type.VectorType()); - default: { - std::string getter = "bb.get"; - if (type.base_type == BASE_TYPE_BOOL) { - getter = "0!=" + getter; - } else if (GenTypeBasic(type) != "byte") { - getter += MakeCamel(GenTypeBasic(type)); - } - return getter; - } - } - } - - // Returns the function name that is able to read a value of the given type. - std::string GenGetterForLookupByKey(flatbuffers::FieldDef *key_field, - const std::string &data_buffer, - const char *num = nullptr) const { - auto type = key_field->value.type; - auto dest_mask = DestinationMask(type, true); - auto dest_cast = DestinationCast(type); - auto getter = data_buffer + ".get"; - if (GenTypeBasic(type) != "byte") { - getter += MakeCamel(GenTypeBasic(type)); - } - getter = dest_cast + getter + "(" + GenOffsetGetter(key_field, num) + ")" + - dest_mask; - return getter; - } - - // Direct mutation is only allowed for scalar fields. - // Hence a setter method will only be generated for such fields. - std::string GenSetter(const Type &type) const { - if (IsScalar(type.base_type)) { - std::string setter = "bb.put"; - if (GenTypeBasic(type) != "byte" && type.base_type != BASE_TYPE_BOOL) { - setter += MakeCamel(GenTypeBasic(type)); - } - return setter; - } else { - return ""; - } - } - - // Returns the method name for use with add/put calls. - std::string GenMethod(const Type &type) const { - return IsScalar(type.base_type) ? MakeCamel(GenTypeBasic(type)) - : (IsStruct(type) ? "Struct" : "Offset"); - } - - // Recursively generate arguments for a constructor, to deal with nested - // structs. - void GenStructArgs(const StructDef &struct_def, std::string *code_ptr, - const char *nameprefix, size_t array_count = 0) const { - std::string &code = *code_ptr; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - const auto &field_type = field.value.type; - const auto array_field = IsArray(field_type); - const auto &type = array_field ? field_type.VectorType() - : DestinationType(field_type, false); - const auto array_cnt = array_field ? (array_count + 1) : array_count; - if (IsStruct(type)) { - // Generate arguments for a struct inside a struct. To ensure names - // don't clash, and to make it obvious these arguments are constructing - // a nested struct, prefix the name with the field name. - GenStructArgs(*field_type.struct_def, code_ptr, - (nameprefix + (field.name + "_")).c_str(), array_cnt); - } else { - code += ", "; - code += GenTypeBasic(type); - for (size_t i = 0; i < array_cnt; i++) code += "[]"; - code += " "; - code += nameprefix; - code += MakeCamel(field.name, false); - } - } - } - - // Recusively generate struct construction statements of the form: - // builder.putType(name); - // and insert manual padding. - void GenStructBody(const StructDef &struct_def, std::string *code_ptr, - const char *nameprefix, size_t index = 0, - bool in_array = false) const { - std::string &code = *code_ptr; - std::string indent((index + 1) * 2, ' '); - code += indent + " builder.prep("; - code += NumToString(struct_def.minalign) + ", "; - code += NumToString(struct_def.bytesize) + ");\n"; - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - const auto &field_type = field.value.type; - if (field.padding) { - code += indent + " builder.pad("; - code += NumToString(field.padding) + ");\n"; - } - if (IsStruct(field_type)) { - GenStructBody(*field_type.struct_def, code_ptr, - (nameprefix + (field.name + "_")).c_str(), index, - in_array); - } else { - const auto &type = - IsArray(field_type) ? field_type.VectorType() : field_type; - const auto index_var = "_idx" + NumToString(index); - if (IsArray(field_type)) { - code += indent + " for (int " + index_var + " = "; - code += NumToString(field_type.fixed_length); - code += "; " + index_var + " > 0; " + index_var + "--) {\n"; - in_array = true; - } - if (IsStruct(type)) { - GenStructBody(*field_type.struct_def, code_ptr, - (nameprefix + (field.name + "_")).c_str(), index + 1, - in_array); - } else { - code += IsArray(field_type) ? " " : ""; - code += indent + " builder.put"; - code += GenMethod(type) + "("; - code += SourceCast(type); - auto argname = nameprefix + MakeCamel(field.name, false); - code += argname; - size_t array_cnt = index + (IsArray(field_type) ? 1 : 0); - for (size_t i = 0; in_array && i < array_cnt; i++) { - code += "[_idx" + NumToString(i) + "-1]"; - } - code += ");\n"; - } - if (IsArray(field_type)) { code += indent + " }\n"; } - } - } - } - - std::string GenByteBufferLength(const char *bb_name) const { - std::string bb_len = bb_name; - bb_len += ".capacity()"; - return bb_len; - } - - std::string GenOffsetGetter(flatbuffers::FieldDef *key_field, - const char *num = nullptr) const { - std::string key_offset = ""; - key_offset += "__offset(" + NumToString(key_field->value.offset) + ", "; - if (num) { - key_offset += num; - key_offset += ", _bb)"; - } else { - key_offset += GenByteBufferLength("bb"); - key_offset += " - tableOffset, bb)"; - } - return key_offset; - } - - std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) const { - std::string key_getter = " "; - key_getter += "int tableOffset = "; - key_getter += "__indirect(vectorLocation + 4 * (start + middle)"; - key_getter += ", bb);\n "; - if (IsString(key_field->value.type)) { - key_getter += "int comp = "; - key_getter += "compareStrings("; - key_getter += GenOffsetGetter(key_field); - key_getter += ", byteKey, bb);\n"; - } else { - auto get_val = GenGetterForLookupByKey(key_field, "bb"); - key_getter += GenTypeNameDest(key_field->value.type) + " val = "; - key_getter += get_val + ";\n"; - key_getter += " int comp = val > key ? 1 : val < key ? -1 : 0;\n"; - } - return key_getter; - } - - std::string GenKeyGetter(flatbuffers::FieldDef *key_field) const { - std::string key_getter = ""; - auto data_buffer = "_bb"; - if (IsString(key_field->value.type)) { - key_getter += " return "; - key_getter += ""; - key_getter += "compareStrings("; - key_getter += GenOffsetGetter(key_field, "o1") + ", "; - key_getter += GenOffsetGetter(key_field, "o2") + ", " + data_buffer + ")"; - key_getter += ";"; - } else { - auto field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o1"); - key_getter += - "\n " + GenTypeNameDest(key_field->value.type) + " val_1 = "; - key_getter += - field_getter + ";\n " + GenTypeNameDest(key_field->value.type); - key_getter += " val_2 = "; - field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o2"); - key_getter += field_getter + ";\n"; - key_getter += " return val_1 > val_2 ? 1 : val_1 < val_2 ? -1 : 0;\n "; - } - return key_getter; - } - - void GenStruct(StructDef &struct_def, std::string *code_ptr) const { - if (struct_def.generated) return; - std::string &code = *code_ptr; - - // Generate a struct accessor class, with methods of the form: - // public type name() { return bb.getType(i + offset); } - // or for tables of the form: - // public type name() { - // int o = __offset(offset); return o != 0 ? bb.getType(o + i) : default; - // } - GenComment(struct_def.doc_comment, code_ptr, &comment_config); - - if (parser_.opts.gen_generated) { - code += "@javax.annotation.Generated(value=\"flatc\")\n"; - } - code += "@SuppressWarnings(\"unused\")\n"; - if (struct_def.attributes.Lookup("private")) { - // For Java, we leave the struct unmarked to indicate package-private - } else { - code += "public "; - } - code += "final class " + struct_def.name; - code += " extends "; - code += struct_def.fixed ? "Struct" : "Table"; - code += " {\n"; - - if (!struct_def.fixed) { - // Generate verson check method. - // Force compile time error if not using the same version runtime. - code += " public static void ValidateVersion() {"; - code += " Constants."; - code += "FLATBUFFERS_2_0_0(); "; - code += "}\n"; - - // Generate a special accessor for the table that when used as the root - // of a FlatBuffer - std::string method_name = "getRootAs" + struct_def.name; - std::string method_signature = - " public static " + struct_def.name + " " + method_name; - - // create convenience method that doesn't require an existing object - code += method_signature + "(ByteBuffer _bb) "; - code += "{ return " + method_name + "(_bb, new " + struct_def.name + - "()); }\n"; - - // create method that allows object reuse - code += - method_signature + "(ByteBuffer _bb, " + struct_def.name + " obj) { "; - code += "_bb.order(ByteOrder.LITTLE_ENDIAN); "; - code += "return (obj.__assign(_bb.getInt(_bb."; - code += "position()"; - code += ") + _bb."; - code += "position()"; - code += ", _bb)); }\n"; - if (parser_.root_struct_def_ == &struct_def) { - if (parser_.file_identifier_.length()) { - // Check if a buffer has the identifier. - code += " public static "; - code += "boolean " + struct_def.name; - code += "BufferHasIdentifier(ByteBuffer _bb) { return "; - code += "__has_identifier(_bb, \""; - code += parser_.file_identifier_; - code += "\"); }\n"; - } - } - } - // Generate the __init method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - code += " public void __init(int _i, ByteBuffer _bb) "; - code += "{ "; - code += "__reset(_i, _bb); "; - code += "}\n"; - code += - " public " + struct_def.name + " __assign(int _i, ByteBuffer _bb) "; - code += "{ __init(_i, _bb); return this; }\n\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - GenComment(field.doc_comment, code_ptr, &comment_config, " "); - std::string type_name = GenTypeGet(field.value.type); - std::string type_name_dest = GenTypeNameDest(field.value.type); - std::string conditional_cast = ""; - std::string optional = ""; - std::string dest_mask = DestinationMask(field.value.type, true); - std::string dest_cast = DestinationCast(field.value.type); - std::string src_cast = SourceCast(field.value.type); - std::string method_start = - " public " + - (field.IsRequired() ? "" : GenNullableAnnotation(field.value.type)) + - GenPureAnnotation(field.value.type) + type_name_dest + optional + - " " + MakeCamel(field.name, false); - std::string obj = "obj"; - - // Most field accessors need to retrieve and test the field offset first, - // this is the prefix code for that: - auto offset_prefix = - IsArray(field.value.type) - ? " { return " - : (" { int o = __offset(" + NumToString(field.value.offset) + - "); return o != 0 ? "); - // Generate the accessors that don't do object reuse. - if (field.value.type.base_type == BASE_TYPE_STRUCT) { - // Calls the accessor that takes an accessor object with a new object. - code += method_start + "() { return "; - code += MakeCamel(field.name, false); - code += "(new "; - code += type_name + "()); }\n"; - } else if (IsVector(field.value.type) && - field.value.type.element == BASE_TYPE_STRUCT) { - // Accessors for vectors of structs also take accessor objects, this - // generates a variant without that argument. - code += method_start + "(int j) { return "; - code += MakeCamel(field.name, false); - code += "(new " + type_name + "(), j); }\n"; - } - - if (field.IsScalarOptional()) { code += GenOptionalScalarCheck(field); } - std::string getter = dest_cast + GenGetter(field.value.type); - code += method_start; - std::string default_cast = ""; - std::string member_suffix = "; "; - if (IsScalar(field.value.type.base_type)) { - code += "()"; - member_suffix += ""; - if (struct_def.fixed) { - code += " { return " + getter; - code += "(bb_pos + "; - code += NumToString(field.value.offset) + ")"; - code += dest_mask; - } else { - code += offset_prefix + getter; - code += "(o + bb_pos)" + dest_mask; - code += " : " + default_cast; - code += GenDefaultValue(field); - } - } else { - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: - code += "(" + type_name + " obj)"; - if (struct_def.fixed) { - code += " { return " + obj + ".__assign("; - code += "bb_pos + " + NumToString(field.value.offset) + ", "; - code += "bb)"; - } else { - code += offset_prefix + conditional_cast; - code += obj + ".__assign("; - code += field.value.type.struct_def->fixed - ? "o + bb_pos" - : "__indirect(o + bb_pos)"; - code += ", bb) : null"; - } - break; - case BASE_TYPE_STRING: - code += "()"; - member_suffix += ""; - code += offset_prefix + getter + "(o + "; - code += "bb_pos) : null"; - break; - case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - code += "("; - if (vectortype.base_type == BASE_TYPE_STRUCT) { - code += type_name + " obj, "; - getter = obj + ".__assign"; - } else if (vectortype.base_type == BASE_TYPE_UNION) { - code += type_name + " obj, "; - } - code += "int j)"; - const auto body = offset_prefix + conditional_cast + getter + "("; - if (vectortype.base_type == BASE_TYPE_UNION) { - code += body + "obj, "; - } else { - code += body; - } - std::string index; - if (IsArray(field.value.type)) { - index += "bb_pos + " + NumToString(field.value.offset) + " + "; - } else { - index += "__vector(o) + "; - } - index += "j * " + NumToString(InlineSize(vectortype)); - if (vectortype.base_type == BASE_TYPE_STRUCT) { - code += vectortype.struct_def->fixed - ? index - : "__indirect(" + index + ")"; - code += ", bb"; - } else { - code += index; - } - code += ")" + dest_mask; - if (!IsArray(field.value.type)) { - code += " : "; - code += - field.value.type.element == BASE_TYPE_BOOL - ? "false" - : (IsScalar(field.value.type.element) ? default_cast + "0" - : "null"); - } - - break; - } - case BASE_TYPE_UNION: - code += "(" + type_name + " obj)" + offset_prefix + getter; - code += "(obj, o + bb_pos) : null"; - break; - default: FLATBUFFERS_ASSERT(0); - } - } - code += member_suffix; - code += "}\n"; - if (IsVector(field.value.type)) { - code += " public int " + MakeCamel(field.name, false); - code += "Length"; - code += "()"; - code += offset_prefix; - code += "__vector_len(o) : 0; "; - code += ""; - code += "}\n"; - // See if we should generate a by-key accessor. - if (field.value.type.element == BASE_TYPE_STRUCT && - !field.value.type.struct_def->fixed) { - auto &sd = *field.value.type.struct_def; - auto &fields = sd.fields.vec; - for (auto kit = fields.begin(); kit != fields.end(); ++kit) { - auto &key_field = **kit; - if (key_field.key) { - auto qualified_name = WrapInNameSpace(sd); - code += " public " + qualified_name + " "; - code += MakeCamel(field.name, false) + "ByKey("; - code += GenTypeNameDest(key_field.value.type) + " key)"; - code += offset_prefix; - code += qualified_name + ".__lookup_by_key("; - code += "null, "; - code += "__vector(o), key, "; - code += "bb) : null; "; - code += "}\n"; - code += " public " + qualified_name + " "; - code += MakeCamel(field.name, false) + "ByKey("; - code += qualified_name + " obj, "; - code += GenTypeNameDest(key_field.value.type) + " key)"; - code += offset_prefix; - code += qualified_name + ".__lookup_by_key(obj, "; - code += "__vector(o), key, "; - code += "bb) : null; "; - code += "}\n"; - break; - } - } - } - } - // Generate the accessors for vector of structs with vector access object - if (IsVector(field.value.type)) { - std::string vector_type_name; - const auto &element_base_type = field.value.type.VectorType().base_type; - if (IsScalar(element_base_type)) { - vector_type_name = MakeCamel(type_name, true) + "Vector"; - } else if (element_base_type == BASE_TYPE_STRING) { - vector_type_name = "StringVector"; - } else if (element_base_type == BASE_TYPE_UNION) { - vector_type_name = "UnionVector"; - } else { - vector_type_name = type_name + ".Vector"; - } - auto vector_method_start = GenNullableAnnotation(field.value.type) + - " public " + vector_type_name + optional + - " " + MakeCamel(field.name, false) + - "Vector"; - code += vector_method_start + "() { return "; - code += MakeCamel(field.name, false) + "Vector"; - code += "(new " + vector_type_name + "()); }\n"; - code += vector_method_start + "(" + vector_type_name + " obj)"; - code += offset_prefix + conditional_cast + obj + ".__assign("; - code += "__vector(o), "; - if (!IsScalar(element_base_type)) { - auto vectortype = field.value.type.VectorType(); - code += NumToString(InlineSize(vectortype)) + ", "; - } - code += "bb) : null" + member_suffix + "}\n"; - } - // Generate a ByteBuffer accessor for strings & vectors of scalars. - if ((IsVector(field.value.type) && - IsScalar(field.value.type.VectorType().base_type)) || - IsString(field.value.type)) { - code += " public ByteBuffer "; - code += MakeCamel(field.name, false); - code += "AsByteBuffer() { return "; - code += "__vector_as_bytebuffer("; - code += NumToString(field.value.offset) + ", "; - code += NumToString(IsString(field.value.type) - ? 1 - : InlineSize(field.value.type.VectorType())); - code += "); }\n"; - code += " public ByteBuffer "; - code += MakeCamel(field.name, false); - code += "InByteBuffer(ByteBuffer _bb) { return "; - code += "__vector_in_bytebuffer(_bb, "; - code += NumToString(field.value.offset) + ", "; - code += NumToString(IsString(field.value.type) - ? 1 - : InlineSize(field.value.type.VectorType())); - code += "); }\n"; - } - // generate object accessors if is nested_flatbuffer - if (field.nested_flatbuffer) { - auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer); - auto nested_method_name = - MakeCamel(field.name, false) + "As" + field.nested_flatbuffer->name; - auto get_nested_method_name = nested_method_name; - code += " public " + nested_type_name + " "; - code += nested_method_name + "() { return "; - code += - get_nested_method_name + "(new " + nested_type_name + "()); }\n"; - code += " public " + nested_type_name + " "; - code += get_nested_method_name + "("; - code += nested_type_name + " obj"; - code += ") { int o = __offset("; - code += NumToString(field.value.offset) + "); "; - code += "return o != 0 ? " + conditional_cast + obj + ".__assign("; - code += ""; - code += "__indirect(__vector(o)), "; - code += "bb) : null; }\n"; - } - // Generate mutators for scalar fields or vectors of scalars. - if (parser_.opts.mutable_buffer) { - auto is_series = (IsSeries(field.value.type)); - const auto &underlying_type = - is_series ? field.value.type.VectorType() : field.value.type; - // Boolean parameters have to be explicitly converted to byte - // representation. - auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL - ? "(byte)(" + field.name + " ? 1 : 0)" - : field.name; - auto mutator_prefix = MakeCamel("mutate", false); - // A vector mutator also needs the index of the vector element it should - // mutate. - auto mutator_params = (is_series ? "(int j, " : "(") + - GenTypeNameDest(underlying_type) + " " + - field.name + ") { "; - auto setter_index = - is_series - ? (IsArray(field.value.type) - ? "bb_pos + " + NumToString(field.value.offset) - : "__vector(o)") + - +" + j * " + NumToString(InlineSize(underlying_type)) - : (struct_def.fixed - ? "bb_pos + " + NumToString(field.value.offset) - : "o + bb_pos"); - if (IsScalar(underlying_type.base_type) && !IsUnion(field.value.type)) { - code += " public "; - code += struct_def.fixed ? "void " : "boolean "; - code += mutator_prefix + MakeCamel(field.name, true); - code += mutator_params; - if (struct_def.fixed) { - code += GenSetter(underlying_type) + "(" + setter_index + ", "; - code += src_cast + setter_parameter + "); }\n"; - } else { - code += "int o = __offset("; - code += NumToString(field.value.offset) + ");"; - code += " if (o != 0) { " + GenSetter(underlying_type); - code += "(" + setter_index + ", " + src_cast + setter_parameter + - "); return true; } else { return false; } }\n"; - } - } - } - if (parser_.opts.java_primitive_has_method && - IsScalar(field.value.type.base_type) && !struct_def.fixed) { - auto vt_offset_constant = " public static final int VT_" + - MakeScreamingCamel(field.name) + " = " + - NumToString(field.value.offset) + ";"; - - code += vt_offset_constant; - code += "\n"; - } - } - code += "\n"; - flatbuffers::FieldDef *key_field = nullptr; - if (struct_def.fixed) { - // create a struct constructor function - code += " public static " + GenOffsetType() + " "; - code += "create"; - code += struct_def.name + "(FlatBufferBuilder builder"; - GenStructArgs(struct_def, code_ptr, ""); - code += ") {\n"; - GenStructBody(struct_def, code_ptr, ""); - code += " return "; - code += GenOffsetConstruct("builder." + std::string("offset()")); - code += ";\n }\n"; - } else { - // Generate a method that creates a table in one go. This is only possible - // when the table has no struct fields, since those have to be created - // inline, and there's no way to do so in Java. - bool has_no_struct_fields = true; - int num_fields = 0; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (IsStruct(field.value.type)) { - has_no_struct_fields = false; - } else { - num_fields++; - } - } - // JVM specifications restrict default constructor params to be < 255. - // Longs and doubles take up 2 units, so we set the limit to be < 127. - if (has_no_struct_fields && num_fields && num_fields < 127) { - // Generate a table constructor of the form: - // public static int createName(FlatBufferBuilder builder, args...) - code += " public static " + GenOffsetType() + " "; - code += "create" + struct_def.name; - code += "(FlatBufferBuilder builder"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - code += ",\n "; - code += GenTypeBasic(DestinationType(field.value.type, false)); - code += " "; - code += field.name; - if (!IsScalar(field.value.type.base_type)) code += "Offset"; - } - code += ") {\n builder."; - code += "startTable("; - code += NumToString(struct_def.fields.vec.size()) + ");\n"; - for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1; - size; size /= 2) { - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - if (!field.deprecated && - (!struct_def.sortbysize || - size == SizeOf(field.value.type.base_type))) { - code += " " + struct_def.name + "."; - code += "add"; - code += MakeCamel(field.name) + "(builder, " + field.name; - if (!IsScalar(field.value.type.base_type)) code += "Offset"; - code += ");\n"; - } - } - } - code += " return " + struct_def.name + "."; - code += "end" + struct_def.name; - code += "(builder);\n }\n\n"; - } - // Generate a set of static methods that allow table construction, - // of the form: - // public static void addName(FlatBufferBuilder builder, short name) - // { builder.addShort(id, name, default); } - // Unlike the Create function, these always work. - code += " public static void start"; - code += struct_def.name; - code += "(FlatBufferBuilder builder) { builder."; - code += "startTable("; - code += NumToString(struct_def.fields.vec.size()) + "); }\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (field.key) key_field = &field; - code += " public static void add"; - code += MakeCamel(field.name); - code += "(FlatBufferBuilder builder, "; - code += GenTypeBasic(DestinationType(field.value.type, false)); - auto argname = MakeCamel(field.name, false); - if (!IsScalar(field.value.type.base_type)) argname += "Offset"; - code += " " + argname + ") { builder.add"; - code += GenMethod(field.value.type) + "("; - code += NumToString(it - struct_def.fields.vec.begin()) + ", "; - code += SourceCastBasic(field.value.type); - code += argname; - code += ", "; - code += SourceCastBasic(field.value.type); - code += GenDefaultValue(field); - code += "); }\n"; - if (IsVector(field.value.type)) { - auto vector_type = field.value.type.VectorType(); - auto alignment = InlineAlignment(vector_type); - auto elem_size = InlineSize(vector_type); - if (!IsStruct(vector_type)) { - // generate a method to create a vector from a java array. - if ((vector_type.base_type == BASE_TYPE_CHAR || - vector_type.base_type == BASE_TYPE_UCHAR)) { - // Handle byte[] and ByteBuffers separately for Java - code += " public static " + GenVectorOffsetType() + " "; - code += "create"; - code += MakeCamel(field.name); - code += "Vector(FlatBufferBuilder builder, byte[] data) "; - code += "{ return builder.createByteVector(data); }\n"; - - code += " public static " + GenVectorOffsetType() + " "; - code += "create"; - code += MakeCamel(field.name); - code += "Vector(FlatBufferBuilder builder, ByteBuffer data) "; - code += "{ return builder.createByteVector(data); }\n"; - } else { - code += " public static " + GenVectorOffsetType() + " "; - code += "create"; - code += MakeCamel(field.name); - code += "Vector(FlatBufferBuilder builder, "; - code += GenTypeBasic(vector_type) + "[] data) "; - code += "{ builder.startVector("; - code += NumToString(elem_size); - code += ", data.length, "; - code += NumToString(alignment); - code += "); for (int i = data."; - code += "length - 1; i >= 0; i--) builder."; - code += "add"; - code += GenMethod(vector_type); - code += "("; - code += SourceCastBasic(vector_type, false); - code += "data[i]"; - code += "); return "; - code += "builder.endVector(); }\n"; - } - } - // Generate a method to start a vector, data to be added manually - // after. - code += " public static void start"; - code += MakeCamel(field.name); - code += "Vector(FlatBufferBuilder builder, int numElems) "; - code += "{ builder.startVector("; - code += NumToString(elem_size); - code += ", numElems, " + NumToString(alignment); - code += "); }\n"; - } - } - code += " public static " + GenOffsetType() + " "; - code += "end" + struct_def.name; - code += "(FlatBufferBuilder builder) {\n int o = builder."; - code += "endTable();\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (!field.deprecated && field.IsRequired()) { - code += " builder.required(o, "; - code += NumToString(field.value.offset); - code += "); // " + field.name + "\n"; - } - } - code += " return " + GenOffsetConstruct("o") + ";\n }\n"; - if (parser_.root_struct_def_ == &struct_def) { - std::string size_prefix[] = { "", "SizePrefixed" }; - for (int i = 0; i < 2; ++i) { - code += " public static void "; - code += "finish" + size_prefix[i] + struct_def.name; - code += "Buffer(FlatBufferBuilder builder, " + GenOffsetType(); - code += " offset) {"; - code += " builder.finish" + size_prefix[i] + "(offset"; - - if (parser_.file_identifier_.length()) - code += ", \"" + parser_.file_identifier_ + "\""; - code += "); }\n"; - } - } - } - // Only generate key compare function for table, - // because `key_field` is not set for struct - if (struct_def.has_key && !struct_def.fixed) { - FLATBUFFERS_ASSERT(key_field); - code += "\n @Override\n protected int keysCompare("; - code += "Integer o1, Integer o2, ByteBuffer _bb) {"; - code += GenKeyGetter(key_field); - code += " }\n"; - - code += "\n public static " + struct_def.name; - code += " __lookup_by_key("; - code += struct_def.name + " obj, "; - code += "int vectorLocation, "; - code += GenTypeNameDest(key_field->value.type); - code += " key, ByteBuffer bb) {\n"; - if (IsString(key_field->value.type)) { - code += " byte[] byteKey = "; - code += "key.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n"; - } - code += " int span = "; - code += "bb.getInt(vectorLocation - 4);\n"; - code += " int start = 0;\n"; - code += " while (span != 0) {\n"; - code += " int middle = span / 2;\n"; - code += GenLookupKeyGetter(key_field); - code += " if (comp > 0) {\n"; - code += " span = middle;\n"; - code += " } else if (comp < 0) {\n"; - code += " middle++;\n"; - code += " start += middle;\n"; - code += " span -= middle;\n"; - code += " } else {\n"; - code += " return "; - code += "(obj == null ? new " + struct_def.name + "() : obj)"; - code += ".__assign(tableOffset, bb);\n"; - code += " }\n }\n"; - code += " return null;\n"; - code += " }\n"; - } - GenVectorAccessObject(struct_def, code_ptr); - code += "}"; - code += "\n\n"; - } - - std::string GenOptionalScalarCheck(FieldDef &field) const { - if (!field.IsScalarOptional()) return ""; - return " public boolean has" + MakeCamel(field.name, true) + - "() { return 0 != __offset(" + NumToString(field.value.offset) + - "); }\n"; - } - - void GenVectorAccessObject(StructDef &struct_def, - std::string *code_ptr) const { - auto &code = *code_ptr; - // Generate a vector of structs accessor class. - code += "\n"; - code += " "; - if (!struct_def.attributes.Lookup("private")) code += "public "; - code += "static "; - code += "final "; - code += "class Vector extends "; - code += "BaseVector {\n"; - - // Generate the __assign method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - std::string method_indent = " "; - code += method_indent + "public Vector "; - code += "__assign(int _vector, int _element_size, ByteBuffer _bb) { "; - code += "__reset(_vector, _element_size, _bb); return this; }\n\n"; - - auto type_name = struct_def.name; - auto method_start = method_indent + "public " + type_name + " get"; - // Generate the accessors that don't do object reuse. - code += method_start + "(int j) { return get"; - code += "(new " + type_name + "(), j); }\n"; - code += method_start + "(" + type_name + " obj, int j) { "; - code += " return obj.__assign("; - std::string index = "__element(j)"; - code += struct_def.fixed ? index : "__indirect(" + index + ", bb)"; - code += ", bb); }\n"; - // See if we should generate a by-key accessor. - if (!struct_def.fixed) { - auto &fields = struct_def.fields.vec; - for (auto kit = fields.begin(); kit != fields.end(); ++kit) { - auto &key_field = **kit; - if (key_field.key) { - auto nullable_annotation = - parser_.opts.gen_nullable ? "@Nullable " : ""; - code += method_indent + nullable_annotation; - code += "public " + type_name + " "; - code += "getByKey("; - code += GenTypeNameDest(key_field.value.type) + " key) { "; - code += " return __lookup_by_key(null, "; - code += "__vector(), key, "; - code += "bb); "; - code += "}\n"; - code += method_indent + nullable_annotation; - code += "public " + type_name + " "; - code += "getByKey("; - code += type_name + " obj, "; - code += GenTypeNameDest(key_field.value.type) + " key) { "; - code += " return __lookup_by_key(obj, "; - code += "__vector(), key, "; - code += "bb); "; - code += "}\n"; - break; - } - } - } - code += " }\n"; - } - - // This tracks the current namespace used to determine if a type need to be - // prefixed by its namespace - const Namespace *cur_name_space_; -}; -} // namespace java - -bool GenerateJava(const Parser &parser, const std::string &path, - const std::string &file_name) { - java::JavaGenerator generator(parser, path, file_name); - return generator.generate(); -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_json_schema.cpp b/contrib/libs/flatbuffers/src/idl_gen_json_schema.cpp deleted file mode 100644 index d58bb84976..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_json_schema.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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 <iostream> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -namespace jsons { - -template<class T> std::string GenFullName(const T *enum_def) { - std::string full_name; - const auto &name_spaces = enum_def->defined_namespace->components; - for (auto ns = name_spaces.cbegin(); ns != name_spaces.cend(); ++ns) { - full_name.append(*ns + "_"); - } - full_name.append(enum_def->name); - return full_name; -} - -template<class T> std::string GenTypeRef(const T *enum_def) { - return "\"$ref\" : \"#/definitions/" + GenFullName(enum_def) + "\""; -} - -std::string GenType(const std::string &name) { - return "\"type\" : \"" + name + "\""; -} - -std::string GenType(BaseType type) { - switch (type) { - case BASE_TYPE_BOOL: return "\"type\" : \"boolean\""; - case BASE_TYPE_CHAR: - return "\"type\" : \"integer\", \"minimum\" : " + - NumToString(std::numeric_limits<int8_t>::min()) + - ", \"maximum\" : " + - NumToString(std::numeric_limits<int8_t>::max()); - case BASE_TYPE_UCHAR: - return "\"type\" : \"integer\", \"minimum\" : 0, \"maximum\" :" + - NumToString(std::numeric_limits<uint8_t>::max()); - case BASE_TYPE_SHORT: - return "\"type\" : \"integer\", \"minimum\" : " + - NumToString(std::numeric_limits<int16_t>::min()) + - ", \"maximum\" : " + - NumToString(std::numeric_limits<int16_t>::max()); - case BASE_TYPE_USHORT: - return "\"type\" : \"integer\", \"minimum\" : 0, \"maximum\" : " + - NumToString(std::numeric_limits<uint16_t>::max()); - case BASE_TYPE_INT: - return "\"type\" : \"integer\", \"minimum\" : " + - NumToString(std::numeric_limits<int32_t>::min()) + - ", \"maximum\" : " + - NumToString(std::numeric_limits<int32_t>::max()); - case BASE_TYPE_UINT: - return "\"type\" : \"integer\", \"minimum\" : 0, \"maximum\" : " + - NumToString(std::numeric_limits<uint32_t>::max()); - case BASE_TYPE_LONG: - return "\"type\" : \"integer\", \"minimum\" : " + - NumToString(std::numeric_limits<int64_t>::min()) + - ", \"maximum\" : " + - NumToString(std::numeric_limits<int64_t>::max()); - case BASE_TYPE_ULONG: - return "\"type\" : \"integer\", \"minimum\" : 0, \"maximum\" : " + - NumToString(std::numeric_limits<uint64_t>::max()); - case BASE_TYPE_FLOAT: - case BASE_TYPE_DOUBLE: return "\"type\" : \"number\""; - case BASE_TYPE_STRING: return "\"type\" : \"string\""; - default: return ""; - } -} - -std::string GenBaseType(const Type &type) { - if (type.struct_def != nullptr) { return GenTypeRef(type.struct_def); } - if (type.enum_def != nullptr) { return GenTypeRef(type.enum_def); } - return GenType(type.base_type); -} - -std::string GenArrayType(const Type &type) { - std::string element_type; - if (type.struct_def != nullptr) { - element_type = GenTypeRef(type.struct_def); - } else if (type.enum_def != nullptr) { - element_type = GenTypeRef(type.enum_def); - } else { - element_type = GenType(type.element); - } - - return "\"type\" : \"array\", \"items\" : {" + element_type + "}"; -} - -std::string GenType(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_VECTOR: { - return GenArrayType(type); - } - case BASE_TYPE_STRUCT: { - return GenTypeRef(type.struct_def); - } - case BASE_TYPE_UNION: { - std::string union_type_string("\"anyOf\": ["); - const auto &union_types = type.enum_def->Vals(); - for (auto ut = union_types.cbegin(); ut < union_types.cend(); ++ut) { - const auto &union_type = *ut; - if (union_type->union_type.base_type == BASE_TYPE_NONE) { continue; } - if (union_type->union_type.base_type == BASE_TYPE_STRUCT) { - union_type_string.append( - "{ " + GenTypeRef(union_type->union_type.struct_def) + " }"); - } - if (union_type != *type.enum_def->Vals().rbegin()) { - union_type_string.append(","); - } - } - union_type_string.append("]"); - return union_type_string; - } - case BASE_TYPE_UTYPE: return GenTypeRef(type.enum_def); - default: { - return GenBaseType(type); - } - } -} - -class JsonSchemaGenerator : public BaseGenerator { - private: - std::string code_; - - public: - JsonSchemaGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", "", "json") {} - - explicit JsonSchemaGenerator(const BaseGenerator &base_generator) - : BaseGenerator(base_generator) {} - - std::string GeneratedFileName(const std::string &path, - const std::string &file_name, - const IDLOptions &options /* unused */) const { - (void)options; - return path + file_name + ".schema.json"; - } - - // If indentation is less than 0, that indicates we don't want any newlines - // either. - std::string NewLine() const { - return parser_.opts.indent_step >= 0 ? "\n" : ""; - } - - std::string Indent(int indent) const { - const auto num_spaces = indent * std::max(parser_.opts.indent_step, 0); - return std::string(num_spaces, ' '); - } - - bool generate() { - code_ = ""; - if (parser_.root_struct_def_ == nullptr) { return false; } - code_ += "{" + NewLine(); - code_ += Indent(1) + - "\"$schema\": \"https://json-schema.org/draft/2019-09/schema\"," + - NewLine(); - code_ += Indent(1) + "\"definitions\": {" + NewLine(); - for (auto e = parser_.enums_.vec.cbegin(); e != parser_.enums_.vec.cend(); - ++e) { - code_ += Indent(2) + "\"" + GenFullName(*e) + "\" : {" + NewLine(); - code_ += Indent(3) + GenType("string") + "," + NewLine(); - auto enumdef(Indent(3) + "\"enum\": ["); - for (auto enum_value = (*e)->Vals().begin(); - enum_value != (*e)->Vals().end(); ++enum_value) { - enumdef.append("\"" + (*enum_value)->name + "\""); - if (*enum_value != (*e)->Vals().back()) { enumdef.append(", "); } - } - enumdef.append("]"); - code_ += enumdef + NewLine(); - code_ += Indent(2) + "}," + NewLine(); // close type - } - for (auto s = parser_.structs_.vec.cbegin(); - s != parser_.structs_.vec.cend(); ++s) { - const auto &structure = *s; - code_ += Indent(2) + "\"" + GenFullName(structure) + "\" : {" + NewLine(); - code_ += Indent(3) + GenType("object") + "," + NewLine(); - std::string comment; - const auto &comment_lines = structure->doc_comment; - for (auto comment_line = comment_lines.cbegin(); - comment_line != comment_lines.cend(); ++comment_line) { - comment.append(*comment_line); - } - if (!comment.empty()) { - std::string description; - if (!EscapeString(comment.c_str(), comment.length(), &description, true, - true)) { - return false; - } - code_ += - Indent(3) + "\"description\" : " + description + "," + NewLine(); - } - code_ += Indent(3) + "\"properties\" : {" + NewLine(); - - const auto &properties = structure->fields.vec; - for (auto prop = properties.cbegin(); prop != properties.cend(); ++prop) { - const auto &property = *prop; - std::string arrayInfo = ""; - if (IsArray(property->value.type)) { - arrayInfo = "," + NewLine() + Indent(8) + "\"minItems\": " + - NumToString(property->value.type.fixed_length) + "," + - NewLine() + Indent(8) + "\"maxItems\": " + - NumToString(property->value.type.fixed_length); - } - std::string deprecated_info = ""; - if (property->deprecated) { - deprecated_info = - "," + NewLine() + Indent(8) + "\"deprecated\" : true,"; - } - std::string typeLine = Indent(4) + "\"" + property->name + "\""; - typeLine += " : {" + NewLine() + Indent(8); - typeLine += GenType(property->value.type); - typeLine += arrayInfo; - typeLine += deprecated_info; - typeLine += NewLine() + Indent(7) + "}"; - if (property != properties.back()) { typeLine.append(","); } - code_ += typeLine + NewLine(); - } - code_ += Indent(3) + "}," + NewLine(); // close properties - - std::vector<FieldDef *> requiredProperties; - std::copy_if(properties.begin(), properties.end(), - back_inserter(requiredProperties), - [](FieldDef const *prop) { return prop->IsRequired(); }); - if (!requiredProperties.empty()) { - auto required_string(Indent(3) + "\"required\" : ["); - for (auto req_prop = requiredProperties.cbegin(); - req_prop != requiredProperties.cend(); ++req_prop) { - required_string.append("\"" + (*req_prop)->name + "\""); - if (*req_prop != requiredProperties.back()) { - required_string.append(", "); - } - } - required_string.append("],"); - code_ += required_string + NewLine(); - } - code_ += Indent(3) + "\"additionalProperties\" : false" + NewLine(); - auto closeType(Indent(2) + "}"); - if (*s != parser_.structs_.vec.back()) { closeType.append(","); } - code_ += closeType + NewLine(); // close type - } - code_ += Indent(1) + "}," + NewLine(); // close definitions - - // mark root type - code_ += Indent(1) + "\"$ref\" : \"#/definitions/" + - GenFullName(parser_.root_struct_def_) + "\"" + NewLine(); - - code_ += "}" + NewLine(); // close schema root - return true; - } - - bool save() const { - const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts); - return SaveFile(file_path.c_str(), code_, false); - } - - const std::string getJson() { return code_; } -}; -} // namespace jsons - -bool GenerateJsonSchema(const Parser &parser, const std::string &path, - const std::string &file_name) { - jsons::JsonSchemaGenerator generator(parser, path, file_name); - if (!generator.generate()) { return false; } - return generator.save(); -} - -bool GenerateJsonSchema(const Parser &parser, std::string *json) { - jsons::JsonSchemaGenerator generator(parser, "", ""); - if (!generator.generate()) { return false; } - *json = generator.getJson(); - return true; -} -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp b/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp deleted file mode 100644 index fb4ce87a67..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp +++ /dev/null @@ -1,1527 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include <functional> -#include <unordered_set> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" -#if defined(FLATBUFFERS_CPP98_STL) -# include <cctype> -#endif // defined(FLATBUFFERS_CPP98_STL) - -namespace flatbuffers { - -namespace kotlin { - -typedef std::map<std::string, std::pair<std::string, std::string> > FbbParamMap; -static TypedFloatConstantGenerator KotlinFloatGen("Double.", "Float.", "NaN", - "POSITIVE_INFINITY", - "NEGATIVE_INFINITY"); - -static const CommentConfig comment_config = { "/**", " *", " */" }; -static const std::string ident_pad = " "; -static const char *keywords[] = { - "package", "as", "typealias", "class", "this", "super", - "val", "var", "fun", "for", "null", "true", - "false", "is", "in", "throw", "return", "break", - "continue", "object", "if", "try", "else", "while", - "do", "when", "interface", "typeof", "Any", "Character" -}; - -// Escape Keywords -static std::string Esc(const std::string &name) { - for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) { - if (name == keywords[i]) { return MakeCamel(name + "_", false); } - } - - return MakeCamel(name, false); -} - -class KotlinGenerator : public BaseGenerator { - public: - KotlinGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", ".", "kt"), - cur_name_space_(nullptr) {} - - KotlinGenerator &operator=(const KotlinGenerator &); - bool generate() FLATBUFFERS_OVERRIDE { - std::string one_file_code; - - cur_name_space_ = parser_.current_namespace_; - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - CodeWriter enumWriter(ident_pad); - auto &enum_def = **it; - if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace; - GenEnum(enum_def, enumWriter); - if (parser_.opts.one_file) { - one_file_code += enumWriter.ToString(); - } else { - if (!SaveType(enum_def.name, *enum_def.defined_namespace, - enumWriter.ToString(), false)) - return false; - } - } - - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - CodeWriter structWriter(ident_pad); - auto &struct_def = **it; - if (!parser_.opts.one_file) - cur_name_space_ = struct_def.defined_namespace; - GenStruct(struct_def, structWriter, parser_.opts); - if (parser_.opts.one_file) { - one_file_code += structWriter.ToString(); - } else { - if (!SaveType(struct_def.name, *struct_def.defined_namespace, - structWriter.ToString(), true)) - return false; - } - } - - if (parser_.opts.one_file) { - return SaveType(file_name_, *parser_.current_namespace_, one_file_code, - true); - } - return true; - } - - // Save out the generated code for a single class while adding - // declaration boilerplate. - bool SaveType(const std::string &defname, const Namespace &ns, - const std::string &classcode, bool needs_includes) const { - if (!classcode.length()) return true; - - std::string code = - "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; - - std::string namespace_name = FullNamespace(".", ns); - if (!namespace_name.empty()) { - code += "package " + namespace_name; - code += "\n\n"; - } - if (needs_includes) { - code += "import java.nio.*\n"; - code += "import kotlin.math.sign\n"; - code += "import com.google.flatbuffers.*\n\n"; - } - code += classcode; - auto filename = NamespaceDir(ns) + defname + ".kt"; - return SaveFile(filename.c_str(), code, false); - } - - const Namespace *CurrentNameSpace() const FLATBUFFERS_OVERRIDE { - return cur_name_space_; - } - - static bool IsEnum(const Type &type) { - return type.enum_def != nullptr && IsInteger(type.base_type); - } - - static std::string GenTypeBasic(const BaseType &type) { - // clang-format off - static const char * const kotlin_typename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE, ...) \ - #KTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - return kotlin_typename[type]; - } - - std::string GenTypePointer(const Type &type) const { - switch (type.base_type) { - case BASE_TYPE_STRING: return "String"; - case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); - case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def); - default: return "Table"; - } - } - - // with the addition of optional scalar types, - // we are adding the nullable '?' operator to return type of a field. - std::string GetterReturnType(const FieldDef &field) const { - auto base_type = field.value.type.base_type; - - auto r_type = GenTypeGet(field.value.type); - if (field.IsScalarOptional() || - // string, structs and unions - (base_type == BASE_TYPE_STRING || base_type == BASE_TYPE_STRUCT || - base_type == BASE_TYPE_UNION) || - // vector of anything not scalar - (base_type == BASE_TYPE_VECTOR && - !IsScalar(field.value.type.VectorType().base_type))) { - r_type += "?"; - } - return r_type; - } - - std::string GenTypeGet(const Type &type) const { - return IsScalar(type.base_type) ? GenTypeBasic(type.base_type) - : GenTypePointer(type); - } - - std::string GenEnumDefaultValue(const FieldDef &field) const { - auto &value = field.value; - FLATBUFFERS_ASSERT(value.type.enum_def); - auto &enum_def = *value.type.enum_def; - auto enum_val = enum_def.FindByValue(value.constant); - return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name) - : value.constant; - } - - // Generate default values to compare against a default value when - // `force_defaults` is `false`. - // Main differences are: - // - Floats are upcasted to doubles - // - Unsigned are casted to signed - std::string GenFBBDefaultValue(const FieldDef &field) const { - if (field.IsScalarOptional()) { - // although default value is null, java API forces us to present a real - // default value for scalars, while adding a field to the buffer. This is - // not a problem because the default can be representing just by not - // calling builder.addMyField() - switch (field.value.type.base_type) { - case BASE_TYPE_DOUBLE: - case BASE_TYPE_FLOAT: return "0.0"; - case BASE_TYPE_BOOL: return "false"; - default: return "0"; - } - } - auto out = GenDefaultValue(field, true); - // All FlatBufferBuilder default floating point values are doubles - if (field.value.type.base_type == BASE_TYPE_FLOAT) { - if (out.find("Float") != std::string::npos) { - out.replace(0, 5, "Double"); - } - } - // Guarantee all values are doubles - if (out.back() == 'f') out.pop_back(); - return out; - } - - // FlatBufferBuilder only store signed types, so this function - // returns a cast for unsigned values - std::string GenFBBValueCast(const FieldDef &field) const { - if (IsUnsigned(field.value.type.base_type)) { - return CastToSigned(field.value.type); - } - return ""; - } - - std::string GenDefaultValue(const FieldDef &field, - bool force_signed = false) const { - auto &value = field.value; - auto base_type = field.value.type.base_type; - - if (field.IsScalarOptional()) { return "null"; } - if (IsFloat(base_type)) { - auto val = KotlinFloatGen.GenFloatConstant(field); - if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') { - val.pop_back(); - } - return val; - } - - if (base_type == BASE_TYPE_BOOL) { - return value.constant == "0" ? "false" : "true"; - } - - std::string suffix = ""; - - if (base_type == BASE_TYPE_LONG || !force_signed) { - suffix = LiteralSuffix(base_type); - } - return value.constant + suffix; - } - - void GenEnum(EnumDef &enum_def, CodeWriter &writer) const { - if (enum_def.generated) return; - - GenerateComment(enum_def.doc_comment, writer, &comment_config); - - writer += "@Suppress(\"unused\")"; - writer += "@ExperimentalUnsignedTypes"; - writer += "class " + Esc(enum_def.name) + " private constructor() {"; - writer.IncrementIdentLevel(); - - GenerateCompanionObject(writer, [&]() { - // Write all properties - auto vals = enum_def.Vals(); - for (auto it = vals.begin(); it != vals.end(); ++it) { - auto &ev = **it; - auto field_type = GenTypeBasic(enum_def.underlying_type.base_type); - auto val = enum_def.ToString(ev); - auto suffix = LiteralSuffix(enum_def.underlying_type.base_type); - writer.SetValue("name", Esc(ev.name)); - writer.SetValue("type", field_type); - writer.SetValue("val", val + suffix); - GenerateComment(ev.doc_comment, writer, &comment_config); - writer += "const val {{name}}: {{type}} = {{val}}"; - } - - // Generate a generate string table for enum values. - // Problem is, if values are very sparse that could generate really - // big tables. Ideally in that case we generate a map lookup - // instead, but for the moment we simply don't output a table at all. - auto range = enum_def.Distance(); - // Average distance between values above which we consider a table - // "too sparse". Change at will. - static const uint64_t kMaxSparseness = 5; - if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) { - GeneratePropertyOneLine(writer, "names", "Array<String>", [&]() { - writer += "arrayOf(\\"; - auto val = enum_def.Vals().front(); - for (auto it = vals.begin(); it != vals.end(); ++it) { - auto ev = *it; - for (auto k = enum_def.Distance(val, ev); k > 1; --k) - writer += "\"\", \\"; - val = ev; - writer += "\"" + (*it)->name + "\"\\"; - if (it + 1 != vals.end()) { writer += ", \\"; } - } - writer += ")"; - }); - GenerateFunOneLine( - writer, "name", "e: Int", "String", - [&]() { - writer += "names[e\\"; - if (enum_def.MinValue()->IsNonZero()) - writer += " - " + enum_def.MinValue()->name + ".toInt()\\"; - writer += "]"; - }, - parser_.opts.gen_jvmstatic); - } - }); - writer.DecrementIdentLevel(); - writer += "}"; - } - - // Returns the function name that is able to read a value of the given type. - std::string ByteBufferGetter(const Type &type, - std::string bb_var_name) const { - switch (type.base_type) { - case BASE_TYPE_STRING: return "__string"; - case BASE_TYPE_STRUCT: return "__struct"; - case BASE_TYPE_UNION: return "__union"; - case BASE_TYPE_VECTOR: - return ByteBufferGetter(type.VectorType(), bb_var_name); - case BASE_TYPE_INT: - case BASE_TYPE_UINT: return bb_var_name + ".getInt"; - case BASE_TYPE_SHORT: - case BASE_TYPE_USHORT: return bb_var_name + ".getShort"; - case BASE_TYPE_ULONG: - case BASE_TYPE_LONG: return bb_var_name + ".getLong"; - case BASE_TYPE_FLOAT: return bb_var_name + ".getFloat"; - case BASE_TYPE_DOUBLE: return bb_var_name + ".getDouble"; - case BASE_TYPE_CHAR: - case BASE_TYPE_UCHAR: - case BASE_TYPE_NONE: - case BASE_TYPE_UTYPE: return bb_var_name + ".get"; - case BASE_TYPE_BOOL: return "0.toByte() != " + bb_var_name + ".get"; - default: - return bb_var_name + ".get" + MakeCamel(GenTypeBasic(type.base_type)); - } - } - - std::string ByteBufferSetter(const Type &type) const { - if (IsScalar(type.base_type)) { - switch (type.base_type) { - case BASE_TYPE_INT: - case BASE_TYPE_UINT: return "bb.putInt"; - case BASE_TYPE_SHORT: - case BASE_TYPE_USHORT: return "bb.putShort"; - case BASE_TYPE_ULONG: - case BASE_TYPE_LONG: return "bb.putLong"; - case BASE_TYPE_FLOAT: return "bb.putFloat"; - case BASE_TYPE_DOUBLE: return "bb.putDouble"; - case BASE_TYPE_CHAR: - case BASE_TYPE_UCHAR: - case BASE_TYPE_BOOL: - case BASE_TYPE_NONE: - case BASE_TYPE_UTYPE: return "bb.put"; - default: return "bb.put" + MakeCamel(GenTypeBasic(type.base_type)); - } - } - return ""; - } - - // Returns the function name that is able to read a value of the given type. - std::string GenLookupByKey(flatbuffers::FieldDef *key_field, - const std::string &bb_var_name, - const char *num = nullptr) const { - auto type = key_field->value.type; - return ByteBufferGetter(type, bb_var_name) + "(" + - GenOffsetGetter(key_field, num) + ")"; - } - - // Returns the method name for use with add/put calls. - static std::string GenMethod(const Type &type) { - return IsScalar(type.base_type) ? ToSignedType(type) - : (IsStruct(type) ? "Struct" : "Offset"); - } - - // Recursively generate arguments for a constructor, to deal with nested - // structs. - static void GenStructArgs(const StructDef &struct_def, CodeWriter &writer, - const char *nameprefix) { - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (IsStruct(field.value.type)) { - // Generate arguments for a struct inside a struct. To ensure - // names don't clash, and to make it obvious these arguments are - // constructing a nested struct, prefix the name with the field - // name. - GenStructArgs(*field.value.type.struct_def, writer, - (nameprefix + (field.name + "_")).c_str()); - } else { - writer += std::string(", ") + nameprefix + "\\"; - writer += MakeCamel(field.name) + ": \\"; - writer += GenTypeBasic(field.value.type.base_type) + "\\"; - } - } - } - - // Recusively generate struct construction statements of the form: - // builder.putType(name); - // and insert manual padding. - static void GenStructBody(const StructDef &struct_def, CodeWriter &writer, - const char *nameprefix) { - writer.SetValue("align", NumToString(struct_def.minalign)); - writer.SetValue("size", NumToString(struct_def.bytesize)); - writer += "builder.prep({{align}}, {{size}})"; - auto fields_vec = struct_def.fields.vec; - for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) { - auto &field = **it; - - if (field.padding) { - writer.SetValue("pad", NumToString(field.padding)); - writer += "builder.pad({{pad}})"; - } - if (IsStruct(field.value.type)) { - GenStructBody(*field.value.type.struct_def, writer, - (nameprefix + (field.name + "_")).c_str()); - } else { - writer.SetValue("type", GenMethod(field.value.type)); - writer.SetValue("argname", nameprefix + MakeCamel(field.name, false)); - writer.SetValue("cast", CastToSigned(field.value.type)); - writer += "builder.put{{type}}({{argname}}{{cast}})"; - } - } - } - - std::string GenByteBufferLength(const char *bb_name) const { - std::string bb_len = bb_name; - bb_len += ".capacity()"; - return bb_len; - } - - std::string GenOffsetGetter(flatbuffers::FieldDef *key_field, - const char *num = nullptr) const { - std::string key_offset = - "__offset(" + NumToString(key_field->value.offset) + ", "; - if (num) { - key_offset += num; - key_offset += ", _bb)"; - } else { - key_offset += GenByteBufferLength("bb"); - key_offset += " - tableOffset, bb)"; - } - return key_offset; - } - - void GenStruct(StructDef &struct_def, CodeWriter &writer, - IDLOptions options) const { - if (struct_def.generated) return; - - GenerateComment(struct_def.doc_comment, writer, &comment_config); - auto fixed = struct_def.fixed; - - writer.SetValue("struct_name", Esc(struct_def.name)); - writer.SetValue("superclass", fixed ? "Struct" : "Table"); - - writer += "@Suppress(\"unused\")"; - writer += "@ExperimentalUnsignedTypes"; - writer += "class {{struct_name}} : {{superclass}}() {\n"; - - writer.IncrementIdentLevel(); - - { - // Generate the __init() method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - GenerateFun(writer, "__init", "_i: Int, _bb: ByteBuffer", "", - [&]() { writer += "__reset(_i, _bb)"; }); - - // Generate assign method - GenerateFun(writer, "__assign", "_i: Int, _bb: ByteBuffer", - Esc(struct_def.name), [&]() { - writer += "__init(_i, _bb)"; - writer += "return this"; - }); - - // Generate all getters - GenerateStructGetters(struct_def, writer); - - // Generate Static Fields - GenerateCompanionObject(writer, [&]() { - if (!struct_def.fixed) { - FieldDef *key_field = nullptr; - - // Generate verson check method. - // Force compile time error if not using the same version - // runtime. - GenerateFunOneLine( - writer, "validateVersion", "", "", - [&]() { writer += "Constants.FLATBUFFERS_2_0_0()"; }, - options.gen_jvmstatic); - - GenerateGetRootAsAccessors(Esc(struct_def.name), writer, options); - GenerateBufferHasIdentifier(struct_def, writer, options); - GenerateTableCreator(struct_def, writer, options); - - GenerateStartStructMethod(struct_def, writer, options); - - // Static Add for fields - auto fields = struct_def.fields.vec; - int field_pos = -1; - for (auto it = fields.begin(); it != fields.end(); ++it) { - auto &field = **it; - field_pos++; - if (field.deprecated) continue; - if (field.key) key_field = &field; - GenerateAddField(NumToString(field_pos), field, writer, options); - - if (IsVector(field.value.type)) { - auto vector_type = field.value.type.VectorType(); - if (!IsStruct(vector_type)) { - GenerateCreateVectorField(field, writer, options); - } - GenerateStartVectorField(field, writer, options); - } - } - - GenerateEndStructMethod(struct_def, writer, options); - auto file_identifier = parser_.file_identifier_; - if (parser_.root_struct_def_ == &struct_def) { - GenerateFinishStructBuffer(struct_def, file_identifier, writer, - options); - GenerateFinishSizePrefixed(struct_def, file_identifier, writer, - options); - } - - if (struct_def.has_key) { - GenerateLookupByKey(key_field, struct_def, writer, options); - } - } else { - GenerateStaticConstructor(struct_def, writer, options); - } - }); - } - - // class closing - writer.DecrementIdentLevel(); - writer += "}"; - } - - // TODO: move key_field to reference instead of pointer - void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def, - CodeWriter &writer, const IDLOptions options) const { - std::stringstream params; - params << "obj: " << Esc(struct_def.name) << "?" - << ", "; - params << "vectorLocation: Int, "; - params << "key: " << GenTypeGet(key_field->value.type) << ", "; - params << "bb: ByteBuffer"; - - auto statements = [&]() { - auto base_type = key_field->value.type.base_type; - writer.SetValue("struct_name", Esc(struct_def.name)); - if (base_type == BASE_TYPE_STRING) { - writer += - "val byteKey = key." - "toByteArray(java.nio.charset.StandardCharsets.UTF_8)"; - } - writer += "var span = bb.getInt(vectorLocation - 4)"; - writer += "var start = 0"; - writer += "while (span != 0) {"; - writer.IncrementIdentLevel(); - writer += "var middle = span / 2"; - writer += - "val tableOffset = __indirect(vector" - "Location + 4 * (start + middle), bb)"; - if (IsString(key_field->value.type)) { - writer += "val comp = compareStrings(\\"; - writer += GenOffsetGetter(key_field) + "\\"; - writer += ", byteKey, bb)"; - } else { - auto cast = CastToUsigned(key_field->value.type); - auto get_val = GenLookupByKey(key_field, "bb"); - writer += "val value = " + get_val + cast; - writer += "val comp = value.compareTo(key)"; - } - writer += "when {"; - writer.IncrementIdentLevel(); - writer += "comp > 0 -> span = middle"; - writer += "comp < 0 -> {"; - writer.IncrementIdentLevel(); - writer += "middle++"; - writer += "start += middle"; - writer += "span -= middle"; - writer.DecrementIdentLevel(); - writer += "}"; // end comp < 0 - writer += "else -> {"; - writer.IncrementIdentLevel(); - writer += "return (obj ?: {{struct_name}}()).__assign(tableOffset, bb)"; - writer.DecrementIdentLevel(); - writer += "}"; // end else - writer.DecrementIdentLevel(); - writer += "}"; // end when - writer.DecrementIdentLevel(); - writer += "}"; // end while - writer += "return null"; - }; - GenerateFun(writer, "__lookup_by_key", params.str(), - Esc(struct_def.name) + "?", statements, options.gen_jvmstatic); - } - - void GenerateFinishSizePrefixed(StructDef &struct_def, - const std::string &identifier, - CodeWriter &writer, - const IDLOptions options) const { - auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : ""; - auto params = "builder: FlatBufferBuilder, offset: Int"; - auto method_name = "finishSizePrefixed" + Esc(struct_def.name) + "Buffer"; - GenerateFunOneLine( - writer, method_name, params, "", - [&]() { writer += "builder.finishSizePrefixed(offset" + id + ")"; }, - options.gen_jvmstatic); - } - void GenerateFinishStructBuffer(StructDef &struct_def, - const std::string &identifier, - CodeWriter &writer, - const IDLOptions options) const { - auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : ""; - auto params = "builder: FlatBufferBuilder, offset: Int"; - auto method_name = "finish" + Esc(struct_def.name) + "Buffer"; - GenerateFunOneLine( - writer, method_name, params, "", - [&]() { writer += "builder.finish(offset" + id + ")"; }, - options.gen_jvmstatic); - } - - void GenerateEndStructMethod(StructDef &struct_def, CodeWriter &writer, - const IDLOptions options) const { - // Generate end{{TableName}}(builder: FlatBufferBuilder) method - auto name = "end" + Esc(struct_def.name); - auto params = "builder: FlatBufferBuilder"; - auto returns = "Int"; - auto field_vec = struct_def.fields.vec; - - GenerateFun( - writer, name, params, returns, - [&]() { - writer += "val o = builder.endTable()"; - writer.IncrementIdentLevel(); - for (auto it = field_vec.begin(); it != field_vec.end(); ++it) { - auto &field = **it; - if (field.deprecated || !field.IsRequired()) { continue; } - writer.SetValue("offset", NumToString(field.value.offset)); - writer += "builder.required(o, {{offset}})"; - } - writer.DecrementIdentLevel(); - writer += "return o"; - }, - options.gen_jvmstatic); - } - - // Generate a method to create a vector from a Kotlin array. - void GenerateCreateVectorField(FieldDef &field, CodeWriter &writer, - const IDLOptions options) const { - auto vector_type = field.value.type.VectorType(); - auto method_name = "create" + MakeCamel(Esc(field.name)) + "Vector"; - auto params = "builder: FlatBufferBuilder, data: " + - GenTypeBasic(vector_type.base_type) + "Array"; - writer.SetValue("size", NumToString(InlineSize(vector_type))); - writer.SetValue("align", NumToString(InlineAlignment(vector_type))); - writer.SetValue("root", GenMethod(vector_type)); - writer.SetValue("cast", CastToSigned(vector_type)); - - GenerateFun( - writer, method_name, params, "Int", - [&]() { - writer += "builder.startVector({{size}}, data.size, {{align}})"; - writer += "for (i in data.size - 1 downTo 0) {"; - writer.IncrementIdentLevel(); - writer += "builder.add{{root}}(data[i]{{cast}})"; - writer.DecrementIdentLevel(); - writer += "}"; - writer += "return builder.endVector()"; - }, - options.gen_jvmstatic); - } - - void GenerateStartVectorField(FieldDef &field, CodeWriter &writer, - const IDLOptions options) const { - // Generate a method to start a vector, data to be added manually - // after. - auto vector_type = field.value.type.VectorType(); - auto params = "builder: FlatBufferBuilder, numElems: Int"; - writer.SetValue("size", NumToString(InlineSize(vector_type))); - writer.SetValue("align", NumToString(InlineAlignment(vector_type))); - - GenerateFunOneLine( - writer, "start" + MakeCamel(Esc(field.name) + "Vector", true), params, - "", - [&]() { - writer += "builder.startVector({{size}}, numElems, {{align}})"; - }, - options.gen_jvmstatic); - } - - void GenerateAddField(std::string field_pos, FieldDef &field, - CodeWriter &writer, const IDLOptions options) const { - auto field_type = GenTypeBasic(field.value.type.base_type); - auto secondArg = MakeCamel(Esc(field.name), false) + ": " + field_type; - - GenerateFunOneLine( - writer, "add" + MakeCamel(Esc(field.name), true), - "builder: FlatBufferBuilder, " + secondArg, "", - [&]() { - auto method = GenMethod(field.value.type); - writer.SetValue("field_name", MakeCamel(Esc(field.name), false)); - writer.SetValue("method_name", method); - writer.SetValue("pos", field_pos); - writer.SetValue("default", GenFBBDefaultValue(field)); - writer.SetValue("cast", GenFBBValueCast(field)); - - writer += "builder.add{{method_name}}({{pos}}, \\"; - writer += "{{field_name}}{{cast}}, {{default}})"; - }, - options.gen_jvmstatic); - } - - static std::string ToSignedType(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_UINT: return GenTypeBasic(BASE_TYPE_INT); - case BASE_TYPE_ULONG: return GenTypeBasic(BASE_TYPE_LONG); - case BASE_TYPE_UCHAR: - case BASE_TYPE_NONE: - case BASE_TYPE_UTYPE: return GenTypeBasic(BASE_TYPE_CHAR); - case BASE_TYPE_USHORT: return GenTypeBasic(BASE_TYPE_SHORT); - case BASE_TYPE_VECTOR: return ToSignedType(type.VectorType()); - default: return GenTypeBasic(type.base_type); - } - } - - static std::string FlexBufferBuilderCast(const std::string &method, - FieldDef &field, bool isFirst) { - auto field_type = GenTypeBasic(field.value.type.base_type); - std::string to_type; - if (method == "Boolean") - to_type = "Boolean"; - else if (method == "Long") - to_type = "Long"; - else if (method == "Int" || method == "Offset" || method == "Struct") - to_type = "Int"; - else if (method == "Byte" || method.empty()) - to_type = isFirst ? "Byte" : "Int"; - else if (method == "Short") - to_type = isFirst ? "Short" : "Int"; - else if (method == "Double") - to_type = "Double"; - else if (method == "Float") - to_type = isFirst ? "Float" : "Double"; - else if (method == "UByte") - - if (field_type != to_type) return ".to" + to_type + "()"; - return ""; - } - - // fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11) - void GenerateStartStructMethod(StructDef &struct_def, CodeWriter &code, - const IDLOptions options) const { - GenerateFunOneLine( - code, "start" + Esc(struct_def.name), "builder: FlatBufferBuilder", "", - [&]() { - code += "builder.startTable(" + - NumToString(struct_def.fields.vec.size()) + ")"; - }, - options.gen_jvmstatic); - } - - void GenerateTableCreator(StructDef &struct_def, CodeWriter &writer, - const IDLOptions options) const { - // Generate a method that creates a table in one go. This is only possible - // when the table has no struct fields, since those have to be created - // inline, and there's no way to do so in Java. - bool has_no_struct_fields = true; - int num_fields = 0; - auto fields_vec = struct_def.fields.vec; - - for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (IsStruct(field.value.type)) { - has_no_struct_fields = false; - } else { - num_fields++; - } - } - // JVM specifications restrict default constructor params to be < 255. - // Longs and doubles take up 2 units, so we set the limit to be < 127. - if (has_no_struct_fields && num_fields && num_fields < 127) { - // Generate a table constructor of the form: - // public static int createName(FlatBufferBuilder builder, args...) - - auto name = "create" + Esc(struct_def.name); - std::stringstream params; - params << "builder: FlatBufferBuilder"; - for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - params << ", " << MakeCamel(Esc(field.name), false); - if (!IsScalar(field.value.type.base_type)) { - params << "Offset: "; - } else { - params << ": "; - } - auto optional = field.IsScalarOptional() ? "?" : ""; - params << GenTypeBasic(field.value.type.base_type) << optional; - } - - GenerateFun( - writer, name, params.str(), "Int", - [&]() { - writer.SetValue("vec_size", NumToString(fields_vec.size())); - - writer += "builder.startTable({{vec_size}})"; - - auto sortbysize = struct_def.sortbysize; - auto largest = sortbysize ? sizeof(largest_scalar_t) : 1; - for (size_t size = largest; size; size /= 2) { - for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); - ++it) { - auto &field = **it; - auto base_type_size = SizeOf(field.value.type.base_type); - if (!field.deprecated && - (!sortbysize || size == base_type_size)) { - writer.SetValue("camel_field_name", - MakeCamel(Esc(field.name), true)); - writer.SetValue("field_name", - MakeCamel(Esc(field.name), false)); - - // we wrap on null check for scalar optionals - writer += field.IsScalarOptional() - ? "{{field_name}}?.run { \\" - : "\\"; - - writer += "add{{camel_field_name}}(builder, {{field_name}}\\"; - if (!IsScalar(field.value.type.base_type)) { - writer += "Offset\\"; - } - // we wrap on null check for scalar optionals - writer += field.IsScalarOptional() ? ") }" : ")"; - } - } - } - writer += "return end{{struct_name}}(builder)"; - }, - options.gen_jvmstatic); - } - } - void GenerateBufferHasIdentifier(StructDef &struct_def, CodeWriter &writer, - IDLOptions options) const { - auto file_identifier = parser_.file_identifier_; - // Check if a buffer has the identifier. - if (parser_.root_struct_def_ != &struct_def || !file_identifier.length()) - return; - auto name = MakeCamel(Esc(struct_def.name), false); - GenerateFunOneLine( - writer, name + "BufferHasIdentifier", "_bb: ByteBuffer", "Boolean", - [&]() { - writer += "__has_identifier(_bb, \"" + file_identifier + "\")"; - }, - options.gen_jvmstatic); - } - - void GenerateStructGetters(StructDef &struct_def, CodeWriter &writer) const { - auto fields_vec = struct_def.fields.vec; - FieldDef *key_field = nullptr; - for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (field.key) key_field = &field; - - GenerateComment(field.doc_comment, writer, &comment_config); - - auto field_name = MakeCamel(Esc(field.name), false); - auto field_type = GenTypeGet(field.value.type); - auto field_default_value = GenDefaultValue(field); - auto return_type = GetterReturnType(field); - auto bbgetter = ByteBufferGetter(field.value.type, "bb"); - auto ucast = CastToUsigned(field); - auto offset_val = NumToString(field.value.offset); - auto offset_prefix = - "val o = __offset(" + offset_val + "); return o != 0 ? "; - auto value_base_type = field.value.type.base_type; - // Most field accessors need to retrieve and test the field offset - // first, this is the offset value for that: - writer.SetValue("offset", NumToString(field.value.offset)); - writer.SetValue("return_type", return_type); - writer.SetValue("field_type", field_type); - writer.SetValue("field_name", field_name); - writer.SetValue("field_default", field_default_value); - writer.SetValue("bbgetter", bbgetter); - writer.SetValue("ucast", ucast); - - // Generate the accessors that don't do object reuse. - if (value_base_type == BASE_TYPE_STRUCT) { - // Calls the accessor that takes an accessor object with a - // new object. - // val pos - // get() = pos(Vec3()) - GenerateGetterOneLine(writer, field_name, return_type, [&]() { - writer += "{{field_name}}({{field_type}}())"; - }); - } else if (value_base_type == BASE_TYPE_VECTOR && - field.value.type.element == BASE_TYPE_STRUCT) { - // Accessors for vectors of structs also take accessor objects, - // this generates a variant without that argument. - // ex: fun weapons(j: Int) = weapons(Weapon(), j) - GenerateFunOneLine(writer, field_name, "j: Int", return_type, [&]() { - writer += "{{field_name}}({{field_type}}(), j)"; - }); - } - - if (IsScalar(value_base_type)) { - if (struct_def.fixed) { - GenerateGetterOneLine(writer, field_name, return_type, [&]() { - writer += "{{bbgetter}}(bb_pos + {{offset}}){{ucast}}"; - }); - } else { - GenerateGetter(writer, field_name, return_type, [&]() { - writer += "val o = __offset({{offset}})"; - writer += - "return if(o != 0) {{bbgetter}}" - "(o + bb_pos){{ucast}} else " - "{{field_default}}"; - }); - } - } else { - switch (value_base_type) { - case BASE_TYPE_STRUCT: - if (struct_def.fixed) { - // create getter with object reuse - // ex: - // fun pos(obj: Vec3) : Vec3? = obj.__assign(bb_pos + 4, bb) - // ? adds nullability annotation - GenerateFunOneLine( - writer, field_name, "obj: " + field_type, return_type, - [&]() { writer += "obj.__assign(bb_pos + {{offset}}, bb)"; }); - } else { - // create getter with object reuse - // ex: - // fun pos(obj: Vec3) : Vec3? { - // val o = __offset(4) - // return if(o != 0) { - // obj.__assign(o + bb_pos, bb) - // else { - // null - // } - // } - // ? adds nullability annotation - GenerateFun( - writer, field_name, "obj: " + field_type, return_type, [&]() { - auto fixed = field.value.type.struct_def->fixed; - - writer.SetValue("seek", Indirect("o + bb_pos", fixed)); - OffsetWrapper( - writer, offset_val, - [&]() { writer += "obj.__assign({{seek}}, bb)"; }, - [&]() { writer += "null"; }); - }); - } - break; - case BASE_TYPE_STRING: - // create string getter - // e.g. - // val Name : String? - // get() = { - // val o = __offset(10) - // return if (o != 0) __string(o + bb_pos) else null - // } - // ? adds nullability annotation - GenerateGetter(writer, field_name, return_type, [&]() { - writer += "val o = __offset({{offset}})"; - writer += "return if (o != 0) __string(o + bb_pos) else null"; - }); - break; - case BASE_TYPE_VECTOR: { - // e.g. - // fun inventory(j: Int) : UByte { - // val o = __offset(14) - // return if (o != 0) { - // bb.get(__vector(o) + j * 1).toUByte() - // } else { - // 0 - // } - // } - - auto vectortype = field.value.type.VectorType(); - std::string params = "j: Int"; - - if (vectortype.base_type == BASE_TYPE_STRUCT || - vectortype.base_type == BASE_TYPE_UNION) { - params = "obj: " + field_type + ", j: Int"; - } - - GenerateFun(writer, field_name, params, return_type, [&]() { - auto inline_size = NumToString(InlineSize(vectortype)); - auto index = "__vector(o) + j * " + inline_size; - auto not_found = NotFoundReturn(field.value.type.element); - auto found = ""; - writer.SetValue("index", index); - switch (vectortype.base_type) { - case BASE_TYPE_STRUCT: { - bool fixed = vectortype.struct_def->fixed; - writer.SetValue("index", Indirect(index, fixed)); - found = "obj.__assign({{index}}, bb)"; - break; - } - case BASE_TYPE_UNION: - found = "{{bbgetter}}(obj, {{index}}){{ucast}}"; - break; - default: found = "{{bbgetter}}({{index}}){{ucast}}"; - } - OffsetWrapper( - writer, offset_val, [&]() { writer += found; }, - [&]() { writer += not_found; }); - }); - break; - } - case BASE_TYPE_UNION: - GenerateFun( - writer, field_name, "obj: " + field_type, return_type, [&]() { - writer += OffsetWrapperOneLine( - offset_val, bbgetter + "(obj, o + bb_pos)", "null"); - }); - break; - default: FLATBUFFERS_ASSERT(0); - } - } - - if (value_base_type == BASE_TYPE_VECTOR) { - // Generate Lenght functions for vectors - GenerateGetter(writer, field_name + "Length", "Int", [&]() { - writer += OffsetWrapperOneLine(offset_val, "__vector_len(o)", "0"); - }); - - // See if we should generate a by-key accessor. - if (field.value.type.element == BASE_TYPE_STRUCT && - !field.value.type.struct_def->fixed) { - auto &sd = *field.value.type.struct_def; - auto &fields = sd.fields.vec; - for (auto kit = fields.begin(); kit != fields.end(); ++kit) { - auto &kfield = **kit; - if (kfield.key) { - auto qualified_name = WrapInNameSpace(sd); - auto name = MakeCamel(Esc(field.name), false) + "ByKey"; - auto params = "key: " + GenTypeGet(kfield.value.type); - auto rtype = qualified_name + "?"; - GenerateFun(writer, name, params, rtype, [&]() { - OffsetWrapper( - writer, offset_val, - [&]() { - writer += qualified_name + - ".__lookup_by_key(null, __vector(o), key, bb)"; - }, - [&]() { writer += "null"; }); - }); - - auto param2 = "obj: " + qualified_name + - ", key: " + GenTypeGet(kfield.value.type); - GenerateFun(writer, name, param2, rtype, [&]() { - OffsetWrapper( - writer, offset_val, - [&]() { - writer += qualified_name + - ".__lookup_by_key(obj, __vector(o), key, bb)"; - }, - [&]() { writer += "null"; }); - }); - - break; - } - } - } - } - - if ((value_base_type == BASE_TYPE_VECTOR && - IsScalar(field.value.type.VectorType().base_type)) || - value_base_type == BASE_TYPE_STRING) { - auto end_idx = - NumToString(value_base_type == BASE_TYPE_STRING - ? 1 - : InlineSize(field.value.type.VectorType())); - // Generate a ByteBuffer accessor for strings & vectors of scalars. - // e.g. - // val inventoryByteBuffer: ByteBuffer - // get = __vector_as_bytebuffer(14, 1) - - GenerateGetterOneLine( - writer, field_name + "AsByteBuffer", "ByteBuffer", [&]() { - writer.SetValue("end", end_idx); - writer += "__vector_as_bytebuffer({{offset}}, {{end}})"; - }); - - // Generate a ByteBuffer accessor for strings & vectors of scalars. - // e.g. - // fun inventoryInByteBuffer(_bb: Bytebuffer): - // ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1) - GenerateFunOneLine( - writer, field_name + "InByteBuffer", "_bb: ByteBuffer", - "ByteBuffer", [&]() { - writer.SetValue("end", end_idx); - writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})"; - }); - } - - // generate object accessors if is nested_flatbuffer - // fun testnestedflatbufferAsMonster() : Monster? - //{ return testnestedflatbufferAsMonster(new Monster()); } - - if (field.nested_flatbuffer) { - auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer); - auto nested_method_name = - field_name + "As" + field.nested_flatbuffer->name; - - GenerateGetterOneLine( - writer, nested_method_name, nested_type_name + "?", [&]() { - writer += nested_method_name + "(" + nested_type_name + "())"; - }); - - GenerateFun(writer, nested_method_name, "obj: " + nested_type_name, - nested_type_name + "?", [&]() { - OffsetWrapper( - writer, offset_val, - [&]() { - writer += - "obj.__assign(__indirect(__vector(o)), bb)"; - }, - [&]() { writer += "null"; }); - }); - } - - // Generate mutators for scalar fields or vectors of scalars. - if (parser_.opts.mutable_buffer) { - auto value_type = field.value.type; - auto underlying_type = value_base_type == BASE_TYPE_VECTOR - ? value_type.VectorType() - : value_type; - auto name = "mutate" + MakeCamel(Esc(field.name), true); - auto size = NumToString(InlineSize(underlying_type)); - auto params = Esc(field.name) + ": " + GenTypeGet(underlying_type); - // A vector mutator also needs the index of the vector element it should - // mutate. - if (value_base_type == BASE_TYPE_VECTOR) params.insert(0, "j: Int, "); - - // Boolean parameters have to be explicitly converted to byte - // representation. - auto setter_parameter = - underlying_type.base_type == BASE_TYPE_BOOL - ? "(if(" + Esc(field.name) + ") 1 else 0).toByte()" - : Esc(field.name); - - auto setter_index = - value_base_type == BASE_TYPE_VECTOR - ? "__vector(o) + j * " + size - : (struct_def.fixed ? "bb_pos + " + offset_val : "o + bb_pos"); - if (IsScalar(value_base_type) || - (value_base_type == BASE_TYPE_VECTOR && - IsScalar(value_type.VectorType().base_type))) { - auto statements = [&]() { - writer.SetValue("bbsetter", ByteBufferSetter(underlying_type)); - writer.SetValue("index", setter_index); - writer.SetValue("params", setter_parameter); - writer.SetValue("cast", CastToSigned(field)); - if (struct_def.fixed) { - writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})"; - } else { - OffsetWrapper( - writer, offset_val, - [&]() { - writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})"; - writer += "true"; - }, - [&]() { writer += "false"; }); - } - }; - - if (struct_def.fixed) { - GenerateFunOneLine(writer, name, params, "ByteBuffer", statements); - } else { - GenerateFun(writer, name, params, "Boolean", statements); - } - } - } - } - if (struct_def.has_key && !struct_def.fixed) { - // Key Comparison method - GenerateOverrideFun( - writer, "keysCompare", "o1: Int, o2: Int, _bb: ByteBuffer", "Int", - [&]() { - if (IsString(key_field->value.type)) { - writer.SetValue("offset", NumToString(key_field->value.offset)); - writer += - " return compareStrings(__offset({{offset}}, o1, " - "_bb), __offset({{offset}}, o2, _bb), _bb)"; - - } else { - auto getter1 = GenLookupByKey(key_field, "_bb", "o1"); - auto getter2 = GenLookupByKey(key_field, "_bb", "o2"); - writer += "val val_1 = " + getter1; - writer += "val val_2 = " + getter2; - writer += "return (val_1 - val_2).sign"; - } - }); - } - } - - static std::string CastToUsigned(const FieldDef &field) { - return CastToUsigned(field.value.type); - } - - static std::string CastToUsigned(const Type type) { - switch (type.base_type) { - case BASE_TYPE_UINT: return ".toUInt()"; - case BASE_TYPE_UCHAR: - case BASE_TYPE_UTYPE: return ".toUByte()"; - case BASE_TYPE_USHORT: return ".toUShort()"; - case BASE_TYPE_ULONG: return ".toULong()"; - case BASE_TYPE_VECTOR: return CastToUsigned(type.VectorType()); - default: return ""; - } - } - - static std::string CastToSigned(const FieldDef &field) { - return CastToSigned(field.value.type); - } - - static std::string CastToSigned(const Type type) { - switch (type.base_type) { - case BASE_TYPE_UINT: return ".toInt()"; - case BASE_TYPE_UCHAR: - case BASE_TYPE_UTYPE: return ".toByte()"; - case BASE_TYPE_USHORT: return ".toShort()"; - case BASE_TYPE_ULONG: return ".toLong()"; - case BASE_TYPE_VECTOR: return CastToSigned(type.VectorType()); - default: return ""; - } - } - - static std::string LiteralSuffix(const BaseType type) { - switch (type) { - case BASE_TYPE_UINT: - case BASE_TYPE_UCHAR: - case BASE_TYPE_UTYPE: - case BASE_TYPE_USHORT: return "u"; - case BASE_TYPE_ULONG: return "UL"; - case BASE_TYPE_LONG: return "L"; - default: return ""; - } - } - - void GenerateCompanionObject(CodeWriter &code, - const std::function<void()> &callback) const { - code += "companion object {"; - code.IncrementIdentLevel(); - callback(); - code.DecrementIdentLevel(); - code += "}"; - } - - // Generate a documentation comment, if available. - void GenerateComment(const std::vector<std::string> &dc, CodeWriter &writer, - const CommentConfig *config) const { - if (dc.begin() == dc.end()) { - // Don't output empty comment blocks with 0 lines of comment content. - return; - } - - if (config != nullptr && config->first_line != nullptr) { - writer += std::string(config->first_line); - } - std::string line_prefix = - ((config != nullptr && config->content_line_prefix != nullptr) - ? config->content_line_prefix - : "///"); - for (auto it = dc.begin(); it != dc.end(); ++it) { - writer += line_prefix + *it; - } - if (config != nullptr && config->last_line != nullptr) { - writer += std::string(config->last_line); - } - } - - static void GenerateGetRootAsAccessors(const std::string &struct_name, - CodeWriter &writer, - IDLOptions options) { - // Generate a special accessor for the table that when used as the root - // ex: fun getRootAsMonster(_bb: ByteBuffer): Monster {...} - writer.SetValue("gr_name", struct_name); - writer.SetValue("gr_method", "getRootAs" + struct_name); - - // create convenience method that doesn't require an existing object - GenerateJvmStaticAnnotation(writer, options.gen_jvmstatic); - writer += "fun {{gr_method}}(_bb: ByteBuffer): {{gr_name}} = \\"; - writer += "{{gr_method}}(_bb, {{gr_name}}())"; - - // create method that allows object reuse - // ex: fun Monster getRootAsMonster(_bb: ByteBuffer, obj: Monster) {...} - GenerateJvmStaticAnnotation(writer, options.gen_jvmstatic); - writer += - "fun {{gr_method}}" - "(_bb: ByteBuffer, obj: {{gr_name}}): {{gr_name}} {"; - writer.IncrementIdentLevel(); - writer += "_bb.order(ByteOrder.LITTLE_ENDIAN)"; - writer += - "return (obj.__assign(_bb.getInt(_bb.position())" - " + _bb.position(), _bb))"; - writer.DecrementIdentLevel(); - writer += "}"; - } - - static void GenerateStaticConstructor(const StructDef &struct_def, - CodeWriter &code, - const IDLOptions options) { - // create a struct constructor function - auto params = StructConstructorParams(struct_def); - GenerateFun( - code, "create" + Esc(struct_def.name), params, "Int", - [&]() { - GenStructBody(struct_def, code, ""); - code += "return builder.offset()"; - }, - options.gen_jvmstatic); - } - - static std::string StructConstructorParams(const StructDef &struct_def, - const std::string &prefix = "") { - // builder: FlatBufferBuilder - std::stringstream out; - auto field_vec = struct_def.fields.vec; - if (prefix.empty()) { out << "builder: FlatBufferBuilder"; } - for (auto it = field_vec.begin(); it != field_vec.end(); ++it) { - auto &field = **it; - if (IsStruct(field.value.type)) { - // Generate arguments for a struct inside a struct. To ensure - // names don't clash, and to make it obvious these arguments are - // constructing a nested struct, prefix the name with the field - // name. - out << StructConstructorParams(*field.value.type.struct_def, - prefix + (Esc(field.name) + "_")); - } else { - out << ", " << prefix << MakeCamel(Esc(field.name), false) << ": " - << GenTypeBasic(field.value.type.base_type); - } - } - return out.str(); - } - - static void GeneratePropertyOneLine(CodeWriter &writer, - const std::string &name, - const std::string &type, - const std::function<void()> &body) { - // Generates Kotlin getter for properties - // e.g.: - // val prop: Mytype = x - writer.SetValue("_name", name); - writer.SetValue("_type", type); - writer += "val {{_name}} : {{_type}} = \\"; - body(); - } - static void GenerateGetterOneLine(CodeWriter &writer, const std::string &name, - const std::string &type, - const std::function<void()> &body) { - // Generates Kotlin getter for properties - // e.g.: - // val prop: Mytype get() = x - writer.SetValue("_name", name); - writer.SetValue("_type", type); - writer += "val {{_name}} : {{_type}} get() = \\"; - body(); - } - - static void GenerateGetter(CodeWriter &writer, const std::string &name, - const std::string &type, - const std::function<void()> &body) { - // Generates Kotlin getter for properties - // e.g.: - // val prop: Mytype - // get() = { - // return x - // } - writer.SetValue("name", name); - writer.SetValue("type", type); - writer += "val {{name}} : {{type}}"; - writer.IncrementIdentLevel(); - writer += "get() {"; - writer.IncrementIdentLevel(); - body(); - writer.DecrementIdentLevel(); - writer += "}"; - writer.DecrementIdentLevel(); - } - - static void GenerateFun(CodeWriter &writer, const std::string &name, - const std::string ¶ms, - const std::string &returnType, - const std::function<void()> &body, - bool gen_jvmstatic = false) { - // Generates Kotlin function - // e.g.: - // fun path(j: Int): Vec3 { - // return path(Vec3(), j) - // } - auto noreturn = returnType.empty(); - writer.SetValue("name", name); - writer.SetValue("params", params); - writer.SetValue("return_type", noreturn ? "" : ": " + returnType); - GenerateJvmStaticAnnotation(writer, gen_jvmstatic); - writer += "fun {{name}}({{params}}) {{return_type}} {"; - writer.IncrementIdentLevel(); - body(); - writer.DecrementIdentLevel(); - writer += "}"; - } - - static void GenerateFunOneLine(CodeWriter &writer, const std::string &name, - const std::string ¶ms, - const std::string &returnType, - const std::function<void()> &body, - bool gen_jvmstatic = false) { - // Generates Kotlin function - // e.g.: - // fun path(j: Int): Vec3 = return path(Vec3(), j) - writer.SetValue("name", name); - writer.SetValue("params", params); - writer.SetValue("return_type_p", - returnType.empty() ? "" : " : " + returnType); - GenerateJvmStaticAnnotation(writer, gen_jvmstatic); - writer += "fun {{name}}({{params}}){{return_type_p}} = \\"; - body(); - } - - static void GenerateOverrideFun(CodeWriter &writer, const std::string &name, - const std::string ¶ms, - const std::string &returnType, - const std::function<void()> &body) { - // Generates Kotlin function - // e.g.: - // override fun path(j: Int): Vec3 = return path(Vec3(), j) - writer += "override \\"; - GenerateFun(writer, name, params, returnType, body); - } - - static void GenerateOverrideFunOneLine(CodeWriter &writer, - const std::string &name, - const std::string ¶ms, - const std::string &returnType, - const std::string &statement) { - // Generates Kotlin function - // e.g.: - // override fun path(j: Int): Vec3 = return path(Vec3(), j) - writer.SetValue("name", name); - writer.SetValue("params", params); - writer.SetValue("return_type", - returnType.empty() ? "" : " : " + returnType); - writer += "override fun {{name}}({{params}}){{return_type}} = \\"; - writer += statement; - } - - static std::string OffsetWrapperOneLine(const std::string &offset, - const std::string &found, - const std::string ¬_found) { - return "val o = __offset(" + offset + "); return if (o != 0) " + found + - " else " + not_found; - } - - static void OffsetWrapper(CodeWriter &code, const std::string &offset, - const std::function<void()> &found, - const std::function<void()> ¬_found) { - code += "val o = __offset(" + offset + ")"; - code += "return if (o != 0) {"; - code.IncrementIdentLevel(); - found(); - code.DecrementIdentLevel(); - code += "} else {"; - code.IncrementIdentLevel(); - not_found(); - code.DecrementIdentLevel(); - code += "}"; - } - - static std::string Indirect(const std::string &index, bool fixed) { - // We apply __indirect() and struct is not fixed. - if (!fixed) return "__indirect(" + index + ")"; - return index; - } - - static std::string NotFoundReturn(BaseType el) { - switch (el) { - case BASE_TYPE_FLOAT: return "0.0f"; - case BASE_TYPE_DOUBLE: return "0.0"; - case BASE_TYPE_BOOL: return "false"; - case BASE_TYPE_LONG: - case BASE_TYPE_INT: - case BASE_TYPE_CHAR: - case BASE_TYPE_SHORT: return "0"; - case BASE_TYPE_UINT: - case BASE_TYPE_UCHAR: - case BASE_TYPE_USHORT: - case BASE_TYPE_UTYPE: return "0u"; - case BASE_TYPE_ULONG: return "0uL"; - default: return "null"; - } - } - - // Prepend @JvmStatic to methods in companion object. - static void GenerateJvmStaticAnnotation(CodeWriter &code, - bool gen_jvmstatic) { - if (gen_jvmstatic) { code += "@JvmStatic"; } - } - - // This tracks the current namespace used to determine if a type need to be - // prefixed by its namespace - const Namespace *cur_name_space_; -}; -} // namespace kotlin - -bool GenerateKotlin(const Parser &parser, const std::string &path, - const std::string &file_name) { - kotlin::KotlinGenerator generator(parser, path, file_name); - return generator.generate(); -} -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_lobster.cpp b/contrib/libs/flatbuffers/src/idl_gen_lobster.cpp deleted file mode 100644 index 6fdd6dc26a..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_lobster.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright 2018 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 - * - * 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 <string> -#include <unordered_set> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { -namespace lobster { - -class LobsterGenerator : public BaseGenerator { - public: - LobsterGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "" /* not used */, "_", - "lobster") { - static const char *const keywords[] = { - "nil", "true", "false", "return", "struct", "class", - "import", "int", "float", "string", "any", "def", - "is", "from", "program", "private", "coroutine", "resource", - "enum", "typeof", "var", "let", "pakfile", "switch", - "case", "default", "namespace", "not", "and", "or", - "bool", - }; - keywords_.insert(std::begin(keywords), std::end(keywords)); - } - - std::string EscapeKeyword(const std::string &name) const { - return keywords_.find(name) == keywords_.end() ? name : name + "_"; - } - - std::string NormalizedName(const Definition &definition) const { - return EscapeKeyword(definition.name); - } - - std::string NormalizedName(const EnumVal &ev) const { - return EscapeKeyword(ev.name); - } - - std::string NamespacedName(const Definition &def) { - return WrapInNameSpace(def.defined_namespace, NormalizedName(def)); - } - - std::string GenTypeName(const Type &type) { - auto bits = NumToString(SizeOf(type.base_type) * 8); - if (IsInteger(type.base_type)) return "int" + bits; - if (IsFloat(type.base_type)) return "float" + bits; - if (IsString(type)) return "string"; - if (type.base_type == BASE_TYPE_STRUCT) return "table"; - return "none"; - } - - std::string LobsterType(const Type &type) { - if (IsFloat(type.base_type)) return "float"; - if (IsScalar(type.base_type) && type.enum_def) - return NormalizedName(*type.enum_def); - if (!IsScalar(type.base_type)) return "flatbuffers_offset"; - return "int"; - } - - // Returns the method name for use with add/put calls. - std::string GenMethod(const Type &type) { - return IsScalar(type.base_type) - ? MakeCamel(GenTypeBasic(type)) - : (IsStruct(type) ? "Struct" : "UOffsetTRelative"); - } - - // This uses Python names for now.. - std::string GenTypeBasic(const Type &type) { - // clang-format off - static const char *ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \ - #PTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - return ctypename[type.base_type]; - } - - // Generate a struct field, conditioned on its child type(s). - void GenStructAccessor(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - GenComment(field.doc_comment, code_ptr, nullptr, " "); - std::string &code = *code_ptr; - auto offsets = NumToString(field.value.offset); - auto def = " def " + NormalizedName(field); - if (IsScalar(field.value.type.base_type)) { - std::string acc; - if (struct_def.fixed) { - acc = "buf_.read_" + GenTypeName(field.value.type) + "_le(pos_ + " + - offsets + ")"; - - } else { - auto defval = field.IsOptional() ? "0" : field.value.constant; - acc = "buf_.flatbuffers_field_" + GenTypeName(field.value.type) + - "(pos_, " + offsets + ", " + defval + ")"; - } - if (field.value.type.enum_def) - acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")"; - if (field.IsOptional()) - acc += ", buf_.flatbuffers_field_present(pos_, " + offsets + ")"; - code += def + "():\n return " + acc + "\n"; - return; - } - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - auto name = NamespacedName(*field.value.type.struct_def); - code += def + "():\n "; - if (struct_def.fixed) { - code += "return " + name + "{ buf_, pos_ + " + offsets + " }\n"; - } else { - code += std::string("let o = buf_.flatbuffers_field_") + - (field.value.type.struct_def->fixed ? "struct" : "table") + - "(pos_, " + offsets + ")\n return if o: " + name + - " { buf_, o } else: nil\n"; - } - break; - } - case BASE_TYPE_STRING: - code += def + - "():\n return buf_.flatbuffers_field_string(pos_, " + - offsets + ")\n"; - break; - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - code += def + "(i:int):\n return "; - if (vectortype.base_type == BASE_TYPE_STRUCT) { - auto start = "buf_.flatbuffers_field_vector(pos_, " + offsets + - ") + i * " + NumToString(InlineSize(vectortype)); - if (!(vectortype.struct_def->fixed)) { - start = "buf_.flatbuffers_indirect(" + start + ")"; - } - code += NamespacedName(*field.value.type.struct_def) + " { buf_, " + - start + " }\n"; - } else { - if (IsString(vectortype)) - code += "buf_.flatbuffers_string"; - else - code += "buf_.read_" + GenTypeName(vectortype) + "_le"; - code += "(buf_.flatbuffers_field_vector(pos_, " + offsets + - ") + i * " + NumToString(InlineSize(vectortype)) + ")\n"; - } - break; - } - case BASE_TYPE_UNION: { - for (auto it = field.value.type.enum_def->Vals().begin(); - it != field.value.type.enum_def->Vals().end(); ++it) { - auto &ev = **it; - if (ev.IsNonZero()) { - code += def + "_as_" + ev.name + "():\n return " + - NamespacedName(*ev.union_type.struct_def) + - " { buf_, buf_.flatbuffers_field_table(pos_, " + offsets + - ") }\n"; - } - } - break; - } - default: FLATBUFFERS_ASSERT(0); - } - if (IsVector(field.value.type)) { - code += def + - "_length():\n return " - "buf_.flatbuffers_field_vector_len(pos_, " + - offsets + ")\n"; - } - } - - // Generate table constructors, conditioned on its members' types. - void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "struct " + NormalizedName(struct_def) + - "Builder:\n b_:flatbuffers_builder\n"; - code += " def start():\n b_.StartObject(" + - NumToString(struct_def.fields.vec.size()) + - ")\n return this\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto offset = it - struct_def.fields.vec.begin(); - code += " def add_" + NormalizedName(field) + "(" + - NormalizedName(field) + ":" + LobsterType(field.value.type) + - "):\n b_.Prepend" + GenMethod(field.value.type) + "Slot(" + - NumToString(offset) + ", " + NormalizedName(field); - if (IsScalar(field.value.type.base_type) && !field.IsOptional()) - code += ", " + field.value.constant; - code += ")\n return this\n"; - } - code += " def end():\n return b_.EndObject()\n\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (IsVector(field.value.type)) { - code += "def " + NormalizedName(struct_def) + "Start" + - MakeCamel(NormalizedName(field)) + - "Vector(b_:flatbuffers_builder, n_:int):\n b_.StartVector("; - auto vector_type = field.value.type.VectorType(); - auto alignment = InlineAlignment(vector_type); - auto elem_size = InlineSize(vector_type); - code += - NumToString(elem_size) + ", n_, " + NumToString(alignment) + ")\n"; - if (vector_type.base_type != BASE_TYPE_STRUCT || - !vector_type.struct_def->fixed) { - code += "def " + NormalizedName(struct_def) + "Create" + - MakeCamel(NormalizedName(field)) + - "Vector(b_:flatbuffers_builder, v_:[" + - LobsterType(vector_type) + "]):\n b_.StartVector(" + - NumToString(elem_size) + ", v_.length, " + - NumToString(alignment) + ")\n reverse(v_) e_: b_.Prepend" + - GenMethod(vector_type) + - "(e_)\n return b_.EndVector(v_.length)\n"; - } - code += "\n"; - } - } - } - - void GenStructPreDecl(const StructDef &struct_def, std::string *code_ptr) { - if (struct_def.generated) return; - std::string &code = *code_ptr; - CheckNameSpace(struct_def, &code); - code += "class " + NormalizedName(struct_def) + "\n\n"; - } - - // Generate struct or table methods. - void GenStruct(const StructDef &struct_def, std::string *code_ptr) { - if (struct_def.generated) return; - std::string &code = *code_ptr; - CheckNameSpace(struct_def, &code); - GenComment(struct_def.doc_comment, code_ptr, nullptr, ""); - code += "class " + NormalizedName(struct_def) + " : flatbuffers_handle\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - GenStructAccessor(struct_def, field, code_ptr); - } - code += "\n"; - if (!struct_def.fixed) { - // Generate a special accessor for the table that has been declared as - // the root type. - code += "def GetRootAs" + NormalizedName(struct_def) + - "(buf:string): return " + NormalizedName(struct_def) + - " { buf, buf.flatbuffers_indirect(0) }\n\n"; - } - if (struct_def.fixed) { - // create a struct constructor function - GenStructBuilder(struct_def, code_ptr); - } else { - // Create a set of functions that allow table construction. - GenTableBuilders(struct_def, code_ptr); - } - } - - // Generate enum declarations. - void GenEnum(const EnumDef &enum_def, std::string *code_ptr) { - if (enum_def.generated) return; - std::string &code = *code_ptr; - CheckNameSpace(enum_def, &code); - GenComment(enum_def.doc_comment, code_ptr, nullptr, ""); - code += "enum " + NormalizedName(enum_def) + ":\n"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - GenComment(ev.doc_comment, code_ptr, nullptr, " "); - code += " " + enum_def.name + "_" + NormalizedName(ev) + " = " + - enum_def.ToString(ev) + "\n"; - } - code += "\n"; - } - - // Recursively generate arguments for a constructor, to deal with nested - // structs. - void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix, - std::string *code_ptr) { - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (IsStruct(field.value.type)) { - // Generate arguments for a struct inside a struct. To ensure names - // don't clash, and to make it obvious these arguments are constructing - // a nested struct, prefix the name with the field name. - StructBuilderArgs(*field.value.type.struct_def, - (nameprefix + (NormalizedName(field) + "_")).c_str(), - code_ptr); - } else { - std::string &code = *code_ptr; - code += ", " + (nameprefix + NormalizedName(field)) + ":" + - LobsterType(field.value.type); - } - } - } - - // Recursively generate struct construction statements and instert manual - // padding. - void StructBuilderBody(const StructDef &struct_def, const char *nameprefix, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += " b_.Prep(" + NumToString(struct_def.minalign) + ", " + - NumToString(struct_def.bytesize) + ")\n"; - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - if (field.padding) - code += " b_.Pad(" + NumToString(field.padding) + ")\n"; - if (IsStruct(field.value.type)) { - StructBuilderBody(*field.value.type.struct_def, - (nameprefix + (NormalizedName(field) + "_")).c_str(), - code_ptr); - } else { - code += " b_.Prepend" + GenMethod(field.value.type) + "(" + - nameprefix + NormalizedName(field) + ")\n"; - } - } - } - - // Create a struct with a builder and the struct's arguments. - void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += - "def Create" + NormalizedName(struct_def) + "(b_:flatbuffers_builder"; - StructBuilderArgs(struct_def, "", code_ptr); - code += "):\n"; - StructBuilderBody(struct_def, "", code_ptr); - code += " return b_.Offset()\n\n"; - } - - void CheckNameSpace(const Definition &def, std::string *code_ptr) { - auto ns = GetNameSpace(def); - if (ns == current_namespace_) return; - current_namespace_ = ns; - std::string &code = *code_ptr; - code += "namespace " + ns + "\n\n"; - } - - bool generate() { - std::string code; - code += std::string("// ") + FlatBuffersGeneratedWarning() + - "\nimport flatbuffers\n\n"; - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - auto &enum_def = **it; - GenEnum(enum_def, &code); - } - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - auto &struct_def = **it; - GenStructPreDecl(struct_def, &code); - } - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - auto &struct_def = **it; - GenStruct(struct_def, &code); - } - return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(), - code, false); - } - - private: - std::unordered_set<std::string> keywords_; - std::string current_namespace_; -}; - -} // namespace lobster - -bool GenerateLobster(const Parser &parser, const std::string &path, - const std::string &file_name) { - lobster::LobsterGenerator generator(parser, path, file_name); - return generator.generate(); -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_lua.cpp b/contrib/libs/flatbuffers/src/idl_gen_lua.cpp deleted file mode 100644 index 9efc435e24..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_lua.cpp +++ /dev/null @@ -1,745 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include <string> -#include <unordered_set> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { -namespace lua { - -// Hardcode spaces per indentation. -const CommentConfig def_comment = { nullptr, "--", nullptr }; -const char *Indent = " "; -const char *Comment = "-- "; -const char *End = "end\n"; -const char *EndFunc = "end\n"; -const char *SelfData = "self.view"; -const char *SelfDataPos = "self.view.pos"; -const char *SelfDataBytes = "self.view.bytes"; - -class LuaGenerator : public BaseGenerator { - public: - LuaGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "" /* not used */, - "" /* not used */, "lua") { - static const char *const keywords[] = { - "and", "break", "do", "else", "elseif", "end", "false", "for", - "function", "goto", "if", "in", "local", "nil", "not", "or", - "repeat", "return", "then", "true", "until", "while" - }; - keywords_.insert(std::begin(keywords), std::end(keywords)); - } - - // Most field accessors need to retrieve and test the field offset first, - // this is the prefix code for that. - std::string OffsetPrefix(const FieldDef &field) { - return std::string(Indent) + "local o = " + SelfData + ":Offset(" + - NumToString(field.value.offset) + ")\n" + Indent + - "if o ~= 0 then\n"; - } - - // Begin a class declaration. - void BeginClass(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "local " + NormalizedName(struct_def) + " = {} -- the module\n"; - code += "local " + NormalizedMetaName(struct_def) + - " = {} -- the class metatable\n"; - code += "\n"; - } - - // Begin enum code with a class declaration. - void BeginEnum(const std::string &class_name, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "local " + class_name + " = {\n"; - } - - std::string EscapeKeyword(const std::string &name) const { - return keywords_.find(name) == keywords_.end() ? name : "_" + name; - } - - std::string NormalizedName(const Definition &definition) const { - return EscapeKeyword(definition.name); - } - - std::string NormalizedName(const EnumVal &ev) const { - return EscapeKeyword(ev.name); - } - - std::string NormalizedMetaName(const Definition &definition) const { - return EscapeKeyword(definition.name) + "_mt"; - } - - // A single enum member. - void EnumMember(const EnumDef &enum_def, const EnumVal &ev, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += std::string(Indent) + NormalizedName(ev) + " = " + - enum_def.ToString(ev) + ",\n"; - } - - // End enum code. - void EndEnum(std::string *code_ptr) { - std::string &code = *code_ptr; - code += "}\n"; - } - - void GenerateNewObjectPrototype(const StructDef &struct_def, - std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "function " + NormalizedName(struct_def) + ".New()\n"; - code += std::string(Indent) + "local o = {}\n"; - code += std::string(Indent) + - "setmetatable(o, {__index = " + NormalizedMetaName(struct_def) + - "})\n"; - code += std::string(Indent) + "return o\n"; - code += EndFunc; - } - - // Initialize a new struct or table from existing data. - void NewRootTypeFromBuffer(const StructDef &struct_def, - std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "function " + NormalizedName(struct_def) + ".GetRootAs" + - NormalizedName(struct_def) + "(buf, offset)\n"; - code += std::string(Indent) + "if type(buf) == \"string\" then\n"; - code += std::string(Indent) + Indent + - "buf = flatbuffers.binaryArray.New(buf)\n"; - code += std::string(Indent) + "end\n"; - code += std::string(Indent) + - "local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)\n"; - code += std::string(Indent) + "local o = " + NormalizedName(struct_def) + - ".New()\n"; - code += std::string(Indent) + "o:Init(buf, n + offset)\n"; - code += std::string(Indent) + "return o\n"; - code += EndFunc; - } - - // Initialize an existing object with other data, to avoid an allocation. - void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - GenReceiver(struct_def, code_ptr); - code += "Init(buf, pos)\n"; - code += - std::string(Indent) + SelfData + " = flatbuffers.view.New(buf, pos)\n"; - code += EndFunc; - } - - // Get the length of a vector. - void GetVectorLen(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)) + "Length()\n"; - code += OffsetPrefix(field); - code += - std::string(Indent) + Indent + "return " + SelfData + ":VectorLen(o)\n"; - code += std::string(Indent) + End; - code += std::string(Indent) + "return 0\n"; - code += EndFunc; - } - - // Get the value of a struct's scalar. - void GetScalarFieldOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - std::string getter = GenGetter(field.value.type); - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "()\n"; - code += std::string(Indent) + "return " + getter; - code += std::string(SelfDataPos) + " + " + NumToString(field.value.offset) + - ")\n"; - code += EndFunc; - } - - // Get the value of a table's scalar. - void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - std::string getter = GenGetter(field.value.type); - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "()\n"; - code += OffsetPrefix(field); - getter += std::string("o + ") + SelfDataPos + ")"; - auto is_bool = field.value.type.base_type == BASE_TYPE_BOOL; - if (is_bool) { getter = "(" + getter + " ~= 0)"; } - code += std::string(Indent) + Indent + "return " + getter + "\n"; - code += std::string(Indent) + End; - std::string default_value; - if (is_bool) { - default_value = field.value.constant == "0" ? "false" : "true"; - } else { - default_value = field.value.constant; - } - code += std::string(Indent) + "return " + default_value + "\n"; - code += EndFunc; - } - - // Get a struct by initializing an existing struct. - // Specific to Struct. - void GetStructFieldOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(obj)\n"; - code += std::string(Indent) + "obj:Init(" + SelfDataBytes + ", " + - SelfDataPos + " + "; - code += NumToString(field.value.offset) + ")\n"; - code += std::string(Indent) + "return obj\n"; - code += EndFunc; - } - - // Get a struct by initializing an existing struct. - // Specific to Table. - void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "()\n"; - code += OffsetPrefix(field); - if (field.value.type.struct_def->fixed) { - code += - std::string(Indent) + Indent + "local x = o + " + SelfDataPos + "\n"; - } else { - code += std::string(Indent) + Indent + "local x = " + SelfData + - ":Indirect(o + " + SelfDataPos + ")\n"; - } - code += std::string(Indent) + Indent + "local obj = require('" + - TypeNameWithNamespace(field) + "').New()\n"; - code += - std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n"; - code += std::string(Indent) + Indent + "return obj\n"; - code += std::string(Indent) + End; - code += EndFunc; - } - - // Get the value of a string. - void GetStringField(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "()\n"; - code += OffsetPrefix(field); - code += - std::string(Indent) + Indent + "return " + GenGetter(field.value.type); - code += std::string("o + ") + SelfDataPos + ")\n"; - code += std::string(Indent) + End; - code += EndFunc; - } - - // Get the value of a union from an object. - void GetUnionField(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)) + "()\n"; - code += OffsetPrefix(field); - - // TODO(rw): this works and is not the good way to it: - // bool is_native_table = TypeName(field) == "*flatbuffers.Table"; - // if (is_native_table) { - // code += std::string(Indent) + Indent + "from flatbuffers.table import - // Table\n"; - //} else { - // code += std::string(Indent) + Indent + - // code += "from ." + TypeName(field) + " import " + TypeName(field) + - // "\n"; - //} - code += - std::string(Indent) + Indent + - "local obj = " - "flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)\n"; - code += std::string(Indent) + Indent + GenGetter(field.value.type) + - "obj, o)\n"; - code += std::string(Indent) + Indent + "return obj\n"; - code += std::string(Indent) + End; - code += EndFunc; - } - - // Get the value of a vector's struct member. - void GetMemberOfVectorOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(j)\n"; - code += OffsetPrefix(field); - code += - std::string(Indent) + Indent + "local x = " + SelfData + ":Vector(o)\n"; - code += std::string(Indent) + Indent + "x = x + ((j-1) * "; - code += NumToString(InlineSize(vectortype)) + ")\n"; - if (!(vectortype.struct_def->fixed)) { - code += - std::string(Indent) + Indent + "x = " + SelfData + ":Indirect(x)\n"; - } - code += std::string(Indent) + Indent + "local obj = require('" + - TypeNameWithNamespace(field) + "').New()\n"; - code += - std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n"; - code += std::string(Indent) + Indent + "return obj\n"; - code += std::string(Indent) + End; - code += EndFunc; - } - - // Get the value of a vector's non-struct member. Uses a named return - // argument to conveniently set the zero value for the result. - void GetMemberOfVectorOfNonStruct(const StructDef &struct_def, - const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(j)\n"; - code += OffsetPrefix(field); - code += - std::string(Indent) + Indent + "local a = " + SelfData + ":Vector(o)\n"; - code += std::string(Indent) + Indent; - code += "return " + GenGetter(field.value.type); - code += "a + ((j-1) * "; - code += NumToString(InlineSize(vectortype)) + "))\n"; - code += std::string(Indent) + End; - if (IsString(vectortype)) { - code += std::string(Indent) + "return ''\n"; - } else { - code += std::string(Indent) + "return 0\n"; - } - code += EndFunc; - } - - // Access a byte/ubyte vector as a string - void AccessByteVectorAsString(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "AsString(start, stop)\n"; - code += std::string(Indent) + "return " + SelfData + ":VectorAsString(" + - NumToString(field.value.offset) + ", start, stop)\n"; - code += EndFunc; - } - - // Begin the creator function signature. - void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += "function " + NormalizedName(struct_def) + ".Create" + - NormalizedName(struct_def); - code += "(builder"; - } - - // Recursively generate arguments for a constructor, to deal with nested - // structs. - void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix, - std::string *code_ptr) { - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (IsStruct(field.value.type)) { - // Generate arguments for a struct inside a struct. To ensure names - // don't clash, and to make it obvious these arguments are constructing - // a nested struct, prefix the name with the field name. - StructBuilderArgs(*field.value.type.struct_def, - (nameprefix + (NormalizedName(field) + "_")).c_str(), - code_ptr); - } else { - std::string &code = *code_ptr; - code += std::string(", ") + nameprefix; - code += MakeCamel(NormalizedName(field), false); - } - } - } - - // End the creator function signature. - void EndBuilderArgs(std::string *code_ptr) { - std::string &code = *code_ptr; - code += ")\n"; - } - - // Recursively generate struct construction statements and instert manual - // padding. - void StructBuilderBody(const StructDef &struct_def, const char *nameprefix, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += std::string(Indent) + "builder:Prep(" + - NumToString(struct_def.minalign) + ", "; - code += NumToString(struct_def.bytesize) + ")\n"; - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - if (field.padding) - code += std::string(Indent) + "builder:Pad(" + - NumToString(field.padding) + ")\n"; - if (IsStruct(field.value.type)) { - StructBuilderBody(*field.value.type.struct_def, - (nameprefix + (NormalizedName(field) + "_")).c_str(), - code_ptr); - } else { - code += - std::string(Indent) + "builder:Prepend" + GenMethod(field) + "("; - code += nameprefix + MakeCamel(NormalizedName(field), false) + ")\n"; - } - } - } - - void EndBuilderBody(std::string *code_ptr) { - std::string &code = *code_ptr; - code += std::string(Indent) + "return builder:Offset()\n"; - code += EndFunc; - } - - // Get the value of a table's starting offset. - void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "function " + NormalizedName(struct_def) + ".Start"; - code += "(builder) "; - code += "builder:StartObject("; - code += NumToString(struct_def.fields.vec.size()); - code += ") end\n"; - } - - // Set the value of a table's field. - void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field, - const size_t offset, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "function " + NormalizedName(struct_def) + ".Add" + - MakeCamel(NormalizedName(field)); - code += "(builder, "; - code += MakeCamel(NormalizedName(field), false); - code += ") "; - code += "builder:Prepend"; - code += GenMethod(field) + "Slot("; - code += NumToString(offset) + ", "; - // todo: i don't need to cast in Lua, but am I missing something? - // if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) { - // code += "flatbuffers.N.UOffsetTFlags.py_type"; - // code += "("; - // code += MakeCamel(NormalizedName(field), false) + ")"; - // } else { - code += MakeCamel(NormalizedName(field), false); - // } - code += ", " + field.value.constant; - code += ") end\n"; - } - - // Set the value of one of the members of a table's vector. - void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += "function " + NormalizedName(struct_def) + ".Start"; - code += MakeCamel(NormalizedName(field)); - code += "Vector(builder, numElems) return builder:StartVector("; - auto vector_type = field.value.type.VectorType(); - auto alignment = InlineAlignment(vector_type); - auto elem_size = InlineSize(vector_type); - code += NumToString(elem_size); - code += ", numElems, " + NumToString(alignment); - code += ") end\n"; - } - - // Get the offset of the end of a table. - void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "function " + NormalizedName(struct_def) + ".End"; - code += "(builder) "; - code += "return builder:EndObject() end\n"; - } - - // Generate the receiver for function signatures. - void GenReceiver(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "function " + NormalizedMetaName(struct_def) + ":"; - } - - // Generate a struct field, conditioned on its child type(s). - void GenStructAccessor(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - GenComment(field.doc_comment, code_ptr, &def_comment); - if (IsScalar(field.value.type.base_type)) { - if (struct_def.fixed) { - GetScalarFieldOfStruct(struct_def, field, code_ptr); - } else { - GetScalarFieldOfTable(struct_def, field, code_ptr); - } - } else { - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: - if (struct_def.fixed) { - GetStructFieldOfStruct(struct_def, field, code_ptr); - } else { - GetStructFieldOfTable(struct_def, field, code_ptr); - } - break; - case BASE_TYPE_STRING: - GetStringField(struct_def, field, code_ptr); - break; - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - if (vectortype.base_type == BASE_TYPE_STRUCT) { - GetMemberOfVectorOfStruct(struct_def, field, code_ptr); - } else { - GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr); - if (vectortype.base_type == BASE_TYPE_CHAR || - vectortype.base_type == BASE_TYPE_UCHAR) { - AccessByteVectorAsString(struct_def, field, code_ptr); - } - } - break; - } - case BASE_TYPE_UNION: GetUnionField(struct_def, field, code_ptr); break; - default: FLATBUFFERS_ASSERT(0); - } - } - if (IsVector(field.value.type)) { - GetVectorLen(struct_def, field, code_ptr); - } - } - - // Generate table constructors, conditioned on its members' types. - void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) { - GetStartOfTable(struct_def, code_ptr); - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - auto offset = it - struct_def.fields.vec.begin(); - BuildFieldOfTable(struct_def, field, offset, code_ptr); - if (IsVector(field.value.type)) { - BuildVectorOfTable(struct_def, field, code_ptr); - } - } - - GetEndOffsetOnTable(struct_def, code_ptr); - } - - // Generate struct or table methods. - void GenStruct(const StructDef &struct_def, std::string *code_ptr) { - if (struct_def.generated) return; - - GenComment(struct_def.doc_comment, code_ptr, &def_comment); - BeginClass(struct_def, code_ptr); - - GenerateNewObjectPrototype(struct_def, code_ptr); - - if (!struct_def.fixed) { - // Generate a special accessor for the table that has been declared as - // the root type. - NewRootTypeFromBuffer(struct_def, code_ptr); - } - - // Generate the Init method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - InitializeExisting(struct_def, code_ptr); - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - GenStructAccessor(struct_def, field, code_ptr); - } - - if (struct_def.fixed) { - // create a struct constructor function - GenStructBuilder(struct_def, code_ptr); - } else { - // Create a set of functions that allow table construction. - GenTableBuilders(struct_def, code_ptr); - } - } - - // Generate enum declarations. - void GenEnum(const EnumDef &enum_def, std::string *code_ptr) { - if (enum_def.generated) return; - - GenComment(enum_def.doc_comment, code_ptr, &def_comment); - BeginEnum(NormalizedName(enum_def), code_ptr); - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - GenComment(ev.doc_comment, code_ptr, &def_comment, Indent); - EnumMember(enum_def, ev, code_ptr); - } - EndEnum(code_ptr); - } - - // Returns the function name that is able to read a value of the given type. - std::string GenGetter(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_STRING: return std::string(SelfData) + ":String("; - case BASE_TYPE_UNION: return std::string(SelfData) + ":Union("; - case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); - default: - return std::string(SelfData) + ":Get(flatbuffers.N." + - MakeCamel(GenTypeGet(type)) + ", "; - } - } - - // Returns the method name for use with add/put calls. - std::string GenMethod(const FieldDef &field) { - return IsScalar(field.value.type.base_type) - ? MakeCamel(GenTypeBasic(field.value.type)) - : (IsStruct(field.value.type) ? "Struct" : "UOffsetTRelative"); - } - - std::string GenTypeBasic(const Type &type) { - // clang-format off - static const char *ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \ - #PTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - return ctypename[type.base_type]; - } - - std::string GenTypePointer(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_STRING: return "string"; - case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); - case BASE_TYPE_STRUCT: return type.struct_def->name; - case BASE_TYPE_UNION: - // fall through - default: return "*flatbuffers.Table"; - } - } - - std::string GenTypeGet(const Type &type) { - return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type); - } - - std::string GetNamespace(const Type &type) { - return type.struct_def->defined_namespace->GetFullyQualifiedName( - type.struct_def->name); - } - - std::string TypeName(const FieldDef &field) { - return GenTypeGet(field.value.type); - } - - std::string TypeNameWithNamespace(const FieldDef &field) { - return GetNamespace(field.value.type); - } - - // Create a struct with a builder and the struct's arguments. - void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) { - BeginBuilderArgs(struct_def, code_ptr); - StructBuilderArgs(struct_def, "", code_ptr); - EndBuilderArgs(code_ptr); - - StructBuilderBody(struct_def, "", code_ptr); - EndBuilderBody(code_ptr); - } - - bool generate() { - if (!generateEnums()) return false; - if (!generateStructs()) return false; - return true; - } - - private: - bool generateEnums() { - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - auto &enum_def = **it; - std::string enumcode; - GenEnum(enum_def, &enumcode); - if (!SaveType(enum_def, enumcode, false)) return false; - } - return true; - } - - bool generateStructs() { - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - auto &struct_def = **it; - std::string declcode; - GenStruct(struct_def, &declcode); - if (!SaveType(struct_def, declcode, true)) return false; - } - return true; - } - - // Begin by declaring namespace and imports. - void BeginFile(const std::string &name_space_name, const bool needs_imports, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += std::string(Comment) + FlatBuffersGeneratedWarning() + "\n\n"; - code += std::string(Comment) + "namespace: " + name_space_name + "\n\n"; - if (needs_imports) { - code += "local flatbuffers = require('flatbuffers')\n\n"; - } - } - - // Save out the generated code for a Lua Table type. - bool SaveType(const Definition &def, const std::string &classcode, - bool needs_imports) { - if (!classcode.length()) return true; - - std::string namespace_dir = path_; - auto &namespaces = def.defined_namespace->components; - for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { - if (it != namespaces.begin()) namespace_dir += kPathSeparator; - namespace_dir += *it; - // std::string init_py_filename = namespace_dir + "/__init__.py"; - // SaveFile(init_py_filename.c_str(), "", false); - } - - std::string code = ""; - BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code); - code += classcode; - code += "\n"; - code += - "return " + NormalizedName(def) + " " + Comment + "return the module"; - std::string filename = - NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".lua"; - return SaveFile(filename.c_str(), code, false); - } - - private: - std::unordered_set<std::string> keywords_; -}; - -} // namespace lua - -bool GenerateLua(const Parser &parser, const std::string &path, - const std::string &file_name) { - lua::LuaGenerator generator(parser, path, file_name); - return generator.generate(); -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_php.cpp b/contrib/libs/flatbuffers/src/idl_gen_php.cpp deleted file mode 100644 index dd3ed68189..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_php.cpp +++ /dev/null @@ -1,939 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include <string> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { -namespace php { -// Hardcode spaces per indentation. -const std::string Indent = " "; -class PhpGenerator : public BaseGenerator { - public: - PhpGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "\\", "\\", "php") {} - bool generate() { - if (!GenerateEnums()) return false; - if (!GenerateStructs()) return false; - return true; - } - - private: - bool GenerateEnums() { - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - auto &enum_def = **it; - std::string enumcode; - GenEnum(enum_def, &enumcode); - if (!SaveType(enum_def, enumcode, false)) return false; - } - return true; - } - - bool GenerateStructs() { - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - auto &struct_def = **it; - std::string declcode; - GenStruct(struct_def, &declcode); - if (!SaveType(struct_def, declcode, true)) return false; - } - return true; - } - - // Begin by declaring namespace and imports. - void BeginFile(const std::string &name_space_name, const bool needs_imports, - std::string *code_ptr) { - auto &code = *code_ptr; - code += "<?php\n"; - code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n"; - - if (!name_space_name.empty()) { - code += "namespace " + name_space_name + ";\n\n"; - } - - if (needs_imports) { - code += "use \\Google\\FlatBuffers\\Struct;\n"; - code += "use \\Google\\FlatBuffers\\Table;\n"; - code += "use \\Google\\FlatBuffers\\ByteBuffer;\n"; - code += "use \\Google\\FlatBuffers\\FlatBufferBuilder;\n"; - code += "\n"; - } - } - - // Save out the generated code for a Php Table type. - bool SaveType(const Definition &def, const std::string &classcode, - bool needs_imports) { - if (!classcode.length()) return true; - - std::string code = ""; - BeginFile(FullNamespace("\\", *def.defined_namespace), needs_imports, - &code); - code += classcode; - - std::string filename = - NamespaceDir(*def.defined_namespace) + def.name + ".php"; - return SaveFile(filename.c_str(), code, false); - } - - // Begin a class declaration. - static void BeginClass(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - if (struct_def.fixed) { - code += "class " + struct_def.name + " extends Struct\n"; - } else { - code += "class " + struct_def.name + " extends Table\n"; - } - code += "{\n"; - } - - static void EndClass(std::string *code_ptr) { - std::string &code = *code_ptr; - code += "}\n"; - } - - // Begin enum code with a class declaration. - static void BeginEnum(const std::string &class_name, std::string *code_ptr) { - std::string &code = *code_ptr; - code += "class " + class_name + "\n{\n"; - } - - // A single enum member. - static void EnumMember(const EnumDef &enum_def, const EnumVal &ev, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += Indent + "const "; - code += ev.name; - code += " = "; - code += enum_def.ToString(ev) + ";\n"; - } - - // End enum code. - static void EndEnum(std::string *code_ptr) { - std::string &code = *code_ptr; - code += "}\n"; - } - - // Initialize a new struct or table from existing data. - static void NewRootTypeFromBuffer(const StructDef &struct_def, - std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @param ByteBuffer $bb\n"; - code += Indent + " * @return " + struct_def.name + "\n"; - code += Indent + " */\n"; - code += Indent + "public static function getRootAs"; - code += struct_def.name; - code += "(ByteBuffer $bb)\n"; - code += Indent + "{\n"; - - code += Indent + Indent + "$obj = new " + struct_def.name + "();\n"; - code += Indent + Indent; - code += "return ($obj->init($bb->getInt($bb->getPosition())"; - code += " + $bb->getPosition(), $bb));\n"; - code += Indent + "}\n\n"; - } - - // Initialize an existing object with other data, to avoid an allocation. - static void InitializeExisting(const StructDef &struct_def, - std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @param int $_i offset\n"; - code += Indent + " * @param ByteBuffer $_bb\n"; - code += Indent + " * @return " + struct_def.name + "\n"; - code += Indent + " **/\n"; - code += Indent + "public function init($_i, ByteBuffer $_bb)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$this->bb_pos = $_i;\n"; - code += Indent + Indent + "$this->bb = $_bb;\n"; - code += Indent + Indent + "return $this;\n"; - code += Indent + "}\n\n"; - } - - // Get the length of a vector. - static void GetVectorLen(const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @return int\n"; - code += Indent + " */\n"; - code += Indent + "public function get"; - code += MakeCamel(field.name) + "Length()\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$o = $this->__offset("; - code += NumToString(field.value.offset) + ");\n"; - code += Indent + Indent; - code += "return $o != 0 ? $this->__vector_len($o) : 0;\n"; - code += Indent + "}\n\n"; - } - - // Get a [ubyte] vector as a byte array. - static void GetUByte(const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @return string\n"; - code += Indent + " */\n"; - code += Indent + "public function get"; - code += MakeCamel(field.name) + "Bytes()\n"; - code += Indent + "{\n"; - code += Indent + Indent + "return $this->__vector_as_bytes("; - code += NumToString(field.value.offset) + ");\n"; - code += Indent + "}\n\n"; - } - - // Get the value of a struct's scalar. - static void GetScalarFieldOfStruct(const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - std::string getter = GenGetter(field.value.type); - - code += Indent + "/**\n"; - code += Indent + " * @return "; - code += GenTypeGet(field.value.type) + "\n"; - code += Indent + " */\n"; - code += Indent + "public function " + getter; - code += MakeCamel(field.name) + "()\n"; - code += Indent + "{\n"; - code += Indent + Indent + "return "; - - code += "$this->bb->get"; - code += MakeCamel(GenTypeGet(field.value.type)); - code += "($this->bb_pos + "; - code += NumToString(field.value.offset) + ")"; - code += ";\n"; - - code += Indent + "}\n\n"; - } - - // Get the value of a table's scalar. - void GetScalarFieldOfTable(const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n"; - code += Indent + " */\n"; - code += Indent + "public function get"; - code += MakeCamel(field.name); - code += "()\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$o = $this->__offset(" + - NumToString(field.value.offset) + ");\n" + Indent + Indent + - "return $o != 0 ? "; - code += "$this->bb->get"; - code += MakeCamel(GenTypeGet(field.value.type)) + "($o + $this->bb_pos)"; - code += " : " + GenDefaultValue(field.value) + ";\n"; - code += Indent + "}\n\n"; - } - - // Get a struct by initializing an existing struct. - // Specific to Struct. - void GetStructFieldOfStruct(const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n"; - code += Indent + " */\n"; - code += Indent + "public function get"; - code += MakeCamel(field.name) + "()\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$obj = new "; - code += GenTypeGet(field.value.type) + "();\n"; - code += Indent + Indent + "$obj->init($this->bb_pos + "; - code += NumToString(field.value.offset) + ", $this->bb);"; - code += "\n" + Indent + Indent + "return $obj;\n"; - code += Indent + "}\n\n"; - } - - // Get a struct by initializing an existing struct. - // Specific to Table. - void GetStructFieldOfTable(const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "public function get"; - code += MakeCamel(field.name); - code += "()\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$obj = new "; - code += MakeCamel(GenTypeGet(field.value.type)) + "();\n"; - code += Indent + Indent + "$o = $this->__offset(" + - NumToString(field.value.offset) + ");\n"; - code += Indent + Indent; - code += "return $o != 0 ? $obj->init("; - if (field.value.type.struct_def->fixed) { - code += "$o + $this->bb_pos, $this->bb) : "; - } else { - code += "$this->__indirect($o + $this->bb_pos), $this->bb) : "; - } - code += GenDefaultValue(field.value) + ";\n"; - code += Indent + "}\n\n"; - } - - // Get the value of a string. - void GetStringField(const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - code += Indent + "public function get"; - code += MakeCamel(field.name); - code += "()\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$o = $this->__offset(" + - NumToString(field.value.offset) + ");\n"; - code += Indent + Indent; - code += "return $o != 0 ? $this->__string($o + $this->bb_pos) : "; - code += GenDefaultValue(field.value) + ";\n"; - code += Indent + "}\n\n"; - } - - // Get the value of a union from an object. - void GetUnionField(const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @return" + GenTypeBasic(field.value.type) + "\n"; - code += Indent + " */\n"; - code += Indent + "public function get"; - code += MakeCamel(field.name) + "($obj)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$o = $this->__offset(" + - NumToString(field.value.offset) + ");\n"; - code += Indent + Indent; - code += "return $o != 0 ? $this->__union($obj, $o) : null;\n"; - code += Indent + "}\n\n"; - } - - // Get the value of a vector's struct member. - void GetMemberOfVectorOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - code += Indent + "/**\n"; - code += Indent + " * @return" + GenTypeBasic(field.value.type) + "\n"; - code += Indent + " */\n"; - code += Indent + "public function get"; - code += MakeCamel(field.name); - code += "($j)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$o = $this->__offset(" + - NumToString(field.value.offset) + ");\n"; - code += Indent + Indent + "$obj = new "; - code += MakeCamel(GenTypeGet(field.value.type)) + "();\n"; - - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: - if (struct_def.fixed) { - code += Indent + Indent; - code += "return $o != 0 ? $obj->init($this->bb_pos +" + - NumToString(field.value.offset) + ", $this->bb) : null;\n"; - } else { - code += Indent + Indent + "return $o != 0 ? $obj->init("; - code += field.value.type.struct_def->fixed - ? "$o + $this->bb_pos" - : "$this->__indirect($o + $this->bb_pos)"; - code += ", $this->bb) : null;\n"; - } - break; - case BASE_TYPE_STRING: - code += "// base_type_string\n"; - // TODO(chobie): do we need this? - break; - case BASE_TYPE_VECTOR: - if (vectortype.base_type == BASE_TYPE_STRUCT) { - code += Indent + Indent + "return $o != 0 ? $obj->init("; - if (vectortype.struct_def->fixed) { - code += "$this->__vector($o) + $j *"; - code += NumToString(InlineSize(vectortype)); - } else { - code += "$this->__indirect($this->__vector($o) + $j * "; - code += NumToString(InlineSize(vectortype)) + ")"; - } - code += ", $this->bb) : null;\n"; - } - break; - case BASE_TYPE_UNION: - code += Indent + Indent + "return $o != 0 ? $this->"; - code += GenGetter(field.value.type) + "($obj, $o); null;\n"; - break; - default: break; - } - - code += Indent + "}\n\n"; - } - - // Get the value of a vector's non-struct member. Uses a named return - // argument to conveniently set the zero value for the result. - void GetMemberOfVectorOfNonStruct(const FieldDef &field, - std::string *code_ptr) { - std::string &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - code += Indent + "/**\n"; - code += Indent + " * @param int offset\n"; - code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n"; - code += Indent + " */\n"; - code += Indent + "public function get"; - code += MakeCamel(field.name); - code += "($j)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$o = $this->__offset(" + - NumToString(field.value.offset) + ");\n"; - - if (IsString(field.value.type.VectorType())) { - code += Indent + Indent; - code += "return $o != 0 ? $this->__string($this->__vector($o) + $j * "; - code += NumToString(InlineSize(vectortype)) + ") : "; - code += GenDefaultValue(field.value) + ";\n"; - } else { - code += Indent + Indent + "return $o != 0 ? $this->bb->get"; - code += MakeCamel(GenTypeGet(field.value.type)); - code += "($this->__vector($o) + $j * "; - code += NumToString(InlineSize(vectortype)) + ") : "; - code += GenDefaultValue(field.value) + ";\n"; - } - code += Indent + "}\n\n"; - } - - // Get the value of a vector's union member. Uses a named return - // argument to conveniently set the zero value for the result. - void GetMemberOfVectorOfUnion(const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - code += Indent + "/**\n"; - code += Indent + " * @param int offset\n"; - code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n"; - code += Indent + " */\n"; - code += Indent + "public function get"; - code += MakeCamel(field.name); - code += "($j, $obj)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$o = $this->__offset(" + - NumToString(field.value.offset) + ");\n"; - code += Indent + Indent + "return $o != 0 ? "; - code += "$this->__union($obj, $this->__vector($o) + $j * "; - code += NumToString(InlineSize(vectortype)) + " - $this->bb_pos) : null;\n"; - code += Indent + "}\n\n"; - } - - // Recursively generate arguments for a constructor, to deal with nested - // structs. - static void StructBuilderArgs(const StructDef &struct_def, - const char *nameprefix, std::string *code_ptr) { - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (IsStruct(field.value.type)) { - // Generate arguments for a struct inside a struct. To ensure names - // don't clash, and to make it obvious - // these arguments are constructing - // a nested struct, prefix the name with the field name. - StructBuilderArgs(*field.value.type.struct_def, - (nameprefix + (field.name + "_")).c_str(), code_ptr); - } else { - std::string &code = *code_ptr; - code += std::string(", $") + nameprefix; - code += MakeCamel(field.name, false); - } - } - } - - // Recursively generate struct construction statements and instert manual - // padding. - static void StructBuilderBody(const StructDef &struct_def, - const char *nameprefix, std::string *code_ptr) { - std::string &code = *code_ptr; - code += Indent + Indent + "$builder->prep("; - code += NumToString(struct_def.minalign) + ", "; - code += NumToString(struct_def.bytesize) + ");\n"; - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - if (field.padding) { - code += Indent + Indent + "$builder->pad("; - code += NumToString(field.padding) + ");\n"; - } - if (IsStruct(field.value.type)) { - StructBuilderBody(*field.value.type.struct_def, - (nameprefix + (field.name + "_")).c_str(), code_ptr); - } else { - code += Indent + Indent + "$builder->put" + GenMethod(field) + "($"; - code += nameprefix + MakeCamel(field.name, false) + ");\n"; - } - } - } - - // Get the value of a table's starting offset. - static void GetStartOfTable(const StructDef &struct_def, - std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @param FlatBufferBuilder $builder\n"; - code += Indent + " * @return void\n"; - code += Indent + " */\n"; - code += Indent + "public static function start" + struct_def.name; - code += "(FlatBufferBuilder $builder)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$builder->StartObject("; - code += NumToString(struct_def.fields.vec.size()); - code += ");\n"; - code += Indent + "}\n\n"; - - code += Indent + "/**\n"; - code += Indent + " * @param FlatBufferBuilder $builder\n"; - code += Indent + " * @return " + struct_def.name + "\n"; - code += Indent + " */\n"; - code += Indent + "public static function create" + struct_def.name; - code += "(FlatBufferBuilder $builder, "; - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - - if (field.deprecated) continue; - code += "$" + field.name; - if (it != struct_def.fields.vec.begin()) { code += ", "; } - } - code += ")\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$builder->startObject("; - code += NumToString(struct_def.fields.vec.size()); - code += ");\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - code += Indent + Indent + "self::add"; - code += MakeCamel(field.name) + "($builder, $" + field.name + ");\n"; - } - - code += Indent + Indent + "$o = $builder->endObject();\n"; - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (!field.deprecated && field.IsRequired()) { - code += Indent + Indent + "$builder->required($o, "; - code += NumToString(field.value.offset); - code += "); // " + field.name + "\n"; - } - } - code += Indent + Indent + "return $o;\n"; - code += Indent + "}\n\n"; - } - - // Set the value of a table's field. - static void BuildFieldOfTable(const FieldDef &field, const size_t offset, - std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @param FlatBufferBuilder $builder\n"; - code += Indent + " * @param " + GenTypeBasic(field.value.type) + "\n"; - code += Indent + " * @return void\n"; - code += Indent + " */\n"; - code += Indent + "public static function "; - code += "add" + MakeCamel(field.name); - code += "(FlatBufferBuilder $builder, "; - code += "$" + MakeCamel(field.name, false); - code += ")\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$builder->add"; - code += GenMethod(field) + "X("; - code += NumToString(offset) + ", "; - - code += "$" + MakeCamel(field.name, false); - code += ", "; - - if (field.value.type.base_type == BASE_TYPE_BOOL) { - code += "false"; - } else { - code += field.value.constant; - } - code += ");\n"; - code += Indent + "}\n\n"; - } - - // Set the value of one of the members of a table's vector. - static void BuildVectorOfTable(const FieldDef &field, std::string *code_ptr) { - std::string &code = *code_ptr; - - auto vector_type = field.value.type.VectorType(); - auto alignment = InlineAlignment(vector_type); - auto elem_size = InlineSize(vector_type); - code += Indent + "/**\n"; - code += Indent + " * @param FlatBufferBuilder $builder\n"; - code += Indent + " * @param array offset array\n"; - code += Indent + " * @return int vector offset\n"; - code += Indent + " */\n"; - code += Indent + "public static function create"; - code += MakeCamel(field.name); - code += "Vector(FlatBufferBuilder $builder, array $data)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$builder->startVector("; - code += NumToString(elem_size); - code += ", count($data), " + NumToString(alignment); - code += ");\n"; - code += Indent + Indent; - code += "for ($i = count($data) - 1; $i >= 0; $i--) {\n"; - if (IsScalar(field.value.type.VectorType().base_type)) { - code += Indent + Indent + Indent; - code += "$builder->put"; - code += MakeCamel(GenTypeBasic(field.value.type.VectorType())); - code += "($data[$i]);\n"; - } else { - code += Indent + Indent + Indent; - code += "$builder->putOffset($data[$i]);\n"; - } - code += Indent + Indent + "}\n"; - code += Indent + Indent + "return $builder->endVector();\n"; - code += Indent + "}\n\n"; - - code += Indent + "/**\n"; - code += Indent + " * @param FlatBufferBuilder $builder\n"; - code += Indent + " * @param int $numElems\n"; - code += Indent + " * @return void\n"; - code += Indent + " */\n"; - code += Indent + "public static function start"; - code += MakeCamel(field.name); - code += "Vector(FlatBufferBuilder $builder, $numElems)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$builder->startVector("; - code += NumToString(elem_size); - code += ", $numElems, " + NumToString(alignment); - code += ");\n"; - code += Indent + "}\n\n"; - } - - // Get the offset of the end of a table. - void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) { - std::string &code = *code_ptr; - - code += Indent + "/**\n"; - code += Indent + " * @param FlatBufferBuilder $builder\n"; - code += Indent + " * @return int table offset\n"; - code += Indent + " */\n"; - code += Indent + "public static function end" + struct_def.name; - code += "(FlatBufferBuilder $builder)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$o = $builder->endObject();\n"; - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (!field.deprecated && field.IsRequired()) { - code += Indent + Indent + "$builder->required($o, "; - code += NumToString(field.value.offset); - code += "); // " + field.name + "\n"; - } - } - code += Indent + Indent + "return $o;\n"; - code += Indent + "}\n"; - - if (parser_.root_struct_def_ == &struct_def) { - code += "\n"; - code += Indent + "public static function finish"; - code += struct_def.name; - code += "Buffer(FlatBufferBuilder $builder, $offset)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$builder->finish($offset"; - - if (parser_.file_identifier_.length()) - code += ", \"" + parser_.file_identifier_ + "\""; - code += ");\n"; - code += Indent + "}\n"; - } - } - - // Generate a struct field, conditioned on its child type(s). - void GenStructAccessor(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - GenComment(field.doc_comment, code_ptr, nullptr, Indent.c_str()); - - if (IsScalar(field.value.type.base_type)) { - if (struct_def.fixed) { - GetScalarFieldOfStruct(field, code_ptr); - } else { - GetScalarFieldOfTable(field, code_ptr); - } - } else { - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: - if (struct_def.fixed) { - GetStructFieldOfStruct(field, code_ptr); - } else { - GetStructFieldOfTable(field, code_ptr); - } - break; - case BASE_TYPE_STRING: GetStringField(field, code_ptr); break; - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - if (vectortype.base_type == BASE_TYPE_UNION) { - GetMemberOfVectorOfUnion(field, code_ptr); - } else if (vectortype.base_type == BASE_TYPE_STRUCT) { - GetMemberOfVectorOfStruct(struct_def, field, code_ptr); - } else { - GetMemberOfVectorOfNonStruct(field, code_ptr); - } - break; - } - case BASE_TYPE_UNION: GetUnionField(field, code_ptr); break; - default: FLATBUFFERS_ASSERT(0); - } - } - if (IsVector(field.value.type)) { - GetVectorLen(field, code_ptr); - if (field.value.type.element == BASE_TYPE_UCHAR) { - GetUByte(field, code_ptr); - } - } - } - - // Generate table constructors, conditioned on its members' types. - void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) { - GetStartOfTable(struct_def, code_ptr); - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - auto offset = it - struct_def.fields.vec.begin(); - if (field.value.type.base_type == BASE_TYPE_UNION) { - std::string &code = *code_ptr; - code += Indent + "public static function add"; - code += MakeCamel(field.name); - code += "(FlatBufferBuilder $builder, $offset)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "$builder->addOffsetX("; - code += NumToString(offset) + ", $offset, 0);\n"; - code += Indent + "}\n\n"; - } else { - BuildFieldOfTable(field, offset, code_ptr); - } - if (IsVector(field.value.type)) { BuildVectorOfTable(field, code_ptr); } - } - - GetEndOffsetOnTable(struct_def, code_ptr); - } - - // Generate struct or table methods. - void GenStruct(const StructDef &struct_def, std::string *code_ptr) { - if (struct_def.generated) return; - - GenComment(struct_def.doc_comment, code_ptr, nullptr); - BeginClass(struct_def, code_ptr); - - if (!struct_def.fixed) { - // Generate a special accessor for the table that has been declared as - // the root type. - NewRootTypeFromBuffer(struct_def, code_ptr); - } - - std::string &code = *code_ptr; - if (!struct_def.fixed) { - if (parser_.file_identifier_.length()) { - // Return the identifier - code += Indent + "public static function " + struct_def.name; - code += "Identifier()\n"; - code += Indent + "{\n"; - code += Indent + Indent + "return \""; - code += parser_.file_identifier_ + "\";\n"; - code += Indent + "}\n\n"; - - // Check if a buffer has the identifier. - code += Indent + "public static function " + struct_def.name; - code += "BufferHasIdentifier(ByteBuffer $buf)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "return self::"; - code += "__has_identifier($buf, self::"; - code += struct_def.name + "Identifier());\n"; - code += Indent + "}\n\n"; - } - - if (parser_.file_extension_.length()) { - // Return the extension - code += Indent + "public static function " + struct_def.name; - code += "Extension()\n"; - code += Indent + "{\n"; - code += Indent + Indent + "return \"" + parser_.file_extension_; - code += "\";\n"; - code += Indent + "}\n\n"; - } - } - - // Generate the Init method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - InitializeExisting(struct_def, code_ptr); - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - GenStructAccessor(struct_def, field, code_ptr); - } - - if (struct_def.fixed) { - // create a struct constructor function - GenStructBuilder(struct_def, code_ptr); - } else { - // Create a set of functions that allow table construction. - GenTableBuilders(struct_def, code_ptr); - } - EndClass(code_ptr); - } - - // Generate enum declarations. - static void GenEnum(const EnumDef &enum_def, std::string *code_ptr) { - if (enum_def.generated) return; - - GenComment(enum_def.doc_comment, code_ptr, nullptr); - BeginEnum(enum_def.name, code_ptr); - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - GenComment(ev.doc_comment, code_ptr, nullptr, Indent.c_str()); - EnumMember(enum_def, ev, code_ptr); - } - - std::string &code = *code_ptr; - code += "\n"; - code += Indent + "private static $names = array(\n"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" + - ev.name + "\",\n"; - } - - code += Indent + ");\n\n"; - code += Indent + "public static function Name($e)\n"; - code += Indent + "{\n"; - code += Indent + Indent + "if (!isset(self::$names[$e])) {\n"; - code += Indent + Indent + Indent + "throw new \\Exception();\n"; - code += Indent + Indent + "}\n"; - code += Indent + Indent + "return self::$names[$e];\n"; - code += Indent + "}\n"; - EndEnum(code_ptr); - } - - // Returns the function name that is able to read a value of the given type. - static std::string GenGetter(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_STRING: return "__string"; - case BASE_TYPE_STRUCT: return "__struct"; - case BASE_TYPE_UNION: return "__union"; - case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); - default: return "Get"; - } - } - - // Returns the method name for use with add/put calls. - static std::string GenMethod(const FieldDef &field) { - return IsScalar(field.value.type.base_type) - ? MakeCamel(GenTypeBasic(field.value.type)) - : (IsStruct(field.value.type) ? "Struct" : "Offset"); - } - - static std::string GenTypeBasic(const Type &type) { - // clang-format off - static const char *ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, ...) \ - #NTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - return ctypename[type.base_type]; - } - - std::string GenDefaultValue(const Value &value) { - if (value.type.enum_def) { - if (auto val = value.type.enum_def->FindByValue(value.constant)) { - return WrapInNameSpace(*value.type.enum_def) + "::" + val->name; - } - } - - switch (value.type.base_type) { - case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true"; - - case BASE_TYPE_STRING: return "null"; - - case BASE_TYPE_LONG: - case BASE_TYPE_ULONG: - if (value.constant != "0") { - int64_t constant = StringToInt(value.constant.c_str()); - return NumToString(constant); - } - return "0"; - - default: return value.constant; - } - } - - static std::string GenTypePointer(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_STRING: return "string"; - case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); - case BASE_TYPE_STRUCT: return type.struct_def->name; - case BASE_TYPE_UNION: - // fall through - default: return "Table"; - } - } - - static std::string GenTypeGet(const Type &type) { - return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type); - } - - // Create a struct with a builder and the struct's arguments. - static void GenStructBuilder(const StructDef &struct_def, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += "\n"; - code += Indent + "/**\n"; - code += Indent + " * @return int offset\n"; - code += Indent + " */\n"; - code += Indent + "public static function create" + struct_def.name; - code += "(FlatBufferBuilder $builder"; - StructBuilderArgs(struct_def, "", code_ptr); - code += ")\n"; - code += Indent + "{\n"; - - StructBuilderBody(struct_def, "", code_ptr); - - code += Indent + Indent + "return $builder->offset();\n"; - code += Indent + "}\n"; - } -}; -} // namespace php - -bool GeneratePhp(const Parser &parser, const std::string &path, - const std::string &file_name) { - php::PhpGenerator generator(parser, path, file_name); - return generator.generate(); -} -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_python.cpp b/contrib/libs/flatbuffers/src/idl_gen_python.cpp deleted file mode 100644 index b3f394ebf9..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_python.cpp +++ /dev/null @@ -1,1782 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include <cctype> -#include <set> -#include <string> -#include <unordered_set> -#include <vector> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { -namespace python { - -// Hardcode spaces per indentation. -const CommentConfig def_comment = { nullptr, "#", nullptr }; -const std::string Indent = " "; - -class PythonGenerator : public BaseGenerator { - public: - PythonGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "" /* not used */, - "" /* not used */, "py"), - float_const_gen_("float('nan')", "float('inf')", "float('-inf')") { - static const char *const keywords[] = { - "False", "None", "True", "and", "as", "assert", "break", - "class", "continue", "def", "del", "elif", "else", "except", - "finally", "for", "from", "global", "if", "import", "in", - "is", "lambda", "nonlocal", "not", "or", "pass", "raise", - "return", "try", "while", "with", "yield" - }; - keywords_.insert(std::begin(keywords), std::end(keywords)); - } - - // Most field accessors need to retrieve and test the field offset first, - // this is the prefix code for that. - std::string OffsetPrefix(const FieldDef &field) { - return "\n" + Indent + Indent + - "o = flatbuffers.number_types.UOffsetTFlags.py_type" + - "(self._tab.Offset(" + NumToString(field.value.offset) + "))\n" + - Indent + Indent + "if o != 0:\n"; - } - - // Begin a class declaration. - void BeginClass(const StructDef &struct_def, std::string *code_ptr) { - auto &code = *code_ptr; - code += "class " + NormalizedName(struct_def) + "(object):\n"; - code += Indent + "__slots__ = ['_tab']"; - code += "\n\n"; - } - - // Begin enum code with a class declaration. - void BeginEnum(const std::string &class_name, std::string *code_ptr) { - auto &code = *code_ptr; - code += "class " + class_name + "(object):\n"; - } - - std::string EscapeKeyword(const std::string &name) const { - return keywords_.find(name) == keywords_.end() ? name : name + "_"; - } - - std::string NormalizedName(const Definition &definition) const { - return EscapeKeyword(definition.name); - } - - std::string NormalizedName(const EnumVal &ev) const { - return EscapeKeyword(ev.name); - } - - // Converts the name of a definition into upper Camel format. - std::string MakeUpperCamel(const Definition &definition) const { - return MakeCamel(NormalizedName(definition), true); - } - - // Converts the name of a definition into lower Camel format. - std::string MakeLowerCamel(const Definition &definition) const { - auto name = MakeCamel(NormalizedName(definition), false); - name[0] = CharToLower(name[0]); - return name; - } - - // Starts a new line and then indents. - std::string GenIndents(int num) { - return "\n" + std::string(num * Indent.length(), ' '); - } - - // A single enum member. - void EnumMember(const EnumDef &enum_def, const EnumVal &ev, - std::string *code_ptr) { - auto &code = *code_ptr; - code += Indent; - code += NormalizedName(ev); - code += " = "; - code += enum_def.ToString(ev) + "\n"; - } - - // End enum code. - void EndEnum(std::string *code_ptr) { - auto &code = *code_ptr; - code += "\n"; - } - - // Initialize a new struct or table from existing data. - void NewRootTypeFromBuffer(const StructDef &struct_def, - std::string *code_ptr) { - auto &code = *code_ptr; - - code += Indent + "@classmethod\n"; - code += Indent + "def GetRootAs"; - code += "(cls, buf, offset=0):"; - code += "\n"; - code += Indent + Indent; - code += "n = flatbuffers.encode.Get"; - code += "(flatbuffers.packer.uoffset, buf, offset)\n"; - code += Indent + Indent + "x = " + NormalizedName(struct_def) + "()\n"; - code += Indent + Indent + "x.Init(buf, n + offset)\n"; - code += Indent + Indent + "return x\n"; - code += "\n"; - - // Add an alias with the old name - code += Indent + "@classmethod\n"; - code += Indent + "def GetRootAs"; - code += NormalizedName(struct_def); - code += "(cls, buf, offset=0):\n"; - code += Indent + Indent + "\"\"\"This method is deprecated. Please switch to GetRootAs.\"\"\"\n"; - code += Indent + Indent + "return cls.GetRootAs(buf, offset)\n"; - } - - // Initialize an existing object with other data, to avoid an allocation. - void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) { - auto &code = *code_ptr; - - GenReceiver(struct_def, code_ptr); - code += "Init(self, buf, pos):\n"; - code += Indent + Indent + "self._tab = flatbuffers.table.Table(buf, pos)\n"; - code += "\n"; - } - - // Get the length of a vector. - void GetVectorLen(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)) + "Length(self"; - code += "):" + OffsetPrefix(field); - code += Indent + Indent + Indent + "return self._tab.VectorLen(o)\n"; - code += Indent + Indent + "return 0\n\n"; - } - - // Determines whether a vector is none or not. - void GetVectorIsNone(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)) + "IsNone(self"; - code += "):"; - code += GenIndents(2) + - "o = flatbuffers.number_types.UOffsetTFlags.py_type" + - "(self._tab.Offset(" + NumToString(field.value.offset) + "))"; - code += GenIndents(2) + "return o == 0"; - code += "\n\n"; - } - - // Get the value of a struct's scalar. - void GetScalarFieldOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - auto &code = *code_ptr; - std::string getter = GenGetter(field.value.type); - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(self): return " + getter; - code += "self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type("; - code += NumToString(field.value.offset) + "))\n"; - } - - // Get the value of a table's scalar. - void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - std::string getter = GenGetter(field.value.type); - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(self):"; - code += OffsetPrefix(field); - getter += "o + self._tab.Pos)"; - auto is_bool = IsBool(field.value.type.base_type); - if (is_bool) { getter = "bool(" + getter + ")"; } - code += Indent + Indent + Indent + "return " + getter + "\n"; - std::string default_value; - if (is_bool) { - default_value = field.value.constant == "0" ? "False" : "True"; - } else { - default_value = IsFloat(field.value.type.base_type) - ? float_const_gen_.GenFloatConstant(field) - : field.value.constant; - } - code += Indent + Indent + "return " + default_value + "\n\n"; - } - - // Get a struct by initializing an existing struct. - // Specific to Struct. - void GetStructFieldOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - auto &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(self, obj):\n"; - code += Indent + Indent + "obj.Init(self._tab.Bytes, self._tab.Pos + "; - code += NumToString(field.value.offset) + ")"; - code += "\n" + Indent + Indent + "return obj\n\n"; - } - - // Get the value of a fixed size array. - void GetArrayOfStruct(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - const auto vec_type = field.value.type.VectorType(); - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - if (IsStruct(vec_type)) { - code += "(self, obj, i):\n"; - code += Indent + Indent + "obj.Init(self._tab.Bytes, self._tab.Pos + "; - code += NumToString(field.value.offset) + " + i * "; - code += NumToString(InlineSize(vec_type)); - code += ")\n" + Indent + Indent + "return obj\n\n"; - } else { - auto getter = GenGetter(vec_type); - code += "(self): return [" + getter; - code += "self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type("; - code += NumToString(field.value.offset) + " + i * "; - code += NumToString(InlineSize(vec_type)); - code += ")) for i in range("; - code += NumToString(field.value.type.fixed_length) + ")]\n"; - } - } - - // Get a struct by initializing an existing struct. - // Specific to Table. - void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(self):"; - code += OffsetPrefix(field); - if (field.value.type.struct_def->fixed) { - code += Indent + Indent + Indent + "x = o + self._tab.Pos\n"; - } else { - code += Indent + Indent + Indent; - code += "x = self._tab.Indirect(o + self._tab.Pos)\n"; - } - if (parser_.opts.include_dependence_headers) { - code += Indent + Indent + Indent; - code += "from " + GenPackageReference(field.value.type) + " import " + - TypeName(field) + "\n"; - } - code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n"; - code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n"; - code += Indent + Indent + Indent + "return obj\n"; - code += Indent + Indent + "return None\n\n"; - } - - // Get the value of a string. - void GetStringField(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(self):"; - code += OffsetPrefix(field); - code += Indent + Indent + Indent + "return " + GenGetter(field.value.type); - code += "o + self._tab.Pos)\n"; - code += Indent + Indent + "return None\n\n"; - } - - // Get the value of a union from an object. - void GetUnionField(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)) + "(self):"; - code += OffsetPrefix(field); - - // TODO(rw): this works and is not the good way to it: - bool is_native_table = TypeName(field) == "*flatbuffers.Table"; - if (is_native_table) { - code += - Indent + Indent + Indent + "from flatbuffers.table import Table\n"; - } else if (parser_.opts.include_dependence_headers) { - code += Indent + Indent + Indent; - code += "from " + GenPackageReference(field.value.type) + " import " + - TypeName(field) + "\n"; - } - code += Indent + Indent + Indent + "obj = Table(bytearray(), 0)\n"; - code += Indent + Indent + Indent + GenGetter(field.value.type); - code += "obj, o)\n" + Indent + Indent + Indent + "return obj\n"; - code += Indent + Indent + "return None\n\n"; - } - - // Generate the package reference when importing a struct or enum from its - // module. - std::string GenPackageReference(const Type &type) { - Namespace *namespaces; - if (type.struct_def) { - namespaces = type.struct_def->defined_namespace; - } else if (type.enum_def) { - namespaces = type.enum_def->defined_namespace; - } else { - return "." + GenTypeGet(type); - } - - return namespaces->GetFullyQualifiedName(GenTypeGet(type)); - } - - // Get the value of a vector's struct member. - void GetMemberOfVectorOfStruct(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - auto &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(self, j):" + OffsetPrefix(field); - code += Indent + Indent + Indent + "x = self._tab.Vector(o)\n"; - code += Indent + Indent + Indent; - code += "x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * "; - code += NumToString(InlineSize(vectortype)) + "\n"; - if (!(vectortype.struct_def->fixed)) { - code += Indent + Indent + Indent + "x = self._tab.Indirect(x)\n"; - } - if (parser_.opts.include_dependence_headers) { - code += Indent + Indent + Indent; - code += "from " + GenPackageReference(field.value.type) + " import " + - TypeName(field) + "\n"; - } - code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n"; - code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n"; - code += Indent + Indent + Indent + "return obj\n"; - code += Indent + Indent + "return None\n\n"; - } - - // Get the value of a vector's non-struct member. Uses a named return - // argument to conveniently set the zero value for the result. - void GetMemberOfVectorOfNonStruct(const StructDef &struct_def, - const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)); - code += "(self, j):"; - code += OffsetPrefix(field); - code += Indent + Indent + Indent + "a = self._tab.Vector(o)\n"; - code += Indent + Indent + Indent; - code += "return " + GenGetter(field.value.type); - code += "a + flatbuffers.number_types.UOffsetTFlags.py_type(j * "; - code += NumToString(InlineSize(vectortype)) + "))\n"; - if (IsString(vectortype)) { - code += Indent + Indent + "return \"\"\n"; - } else { - code += Indent + Indent + "return 0\n"; - } - code += "\n"; - } - - // Returns a non-struct vector as a numpy array. Much faster - // than iterating over the vector element by element. - void GetVectorOfNonStructAsNumpy(const StructDef &struct_def, - const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - auto vectortype = field.value.type.VectorType(); - - // Currently, we only support accessing as numpy array if - // the vector type is a scalar. - if (!(IsScalar(vectortype.base_type))) { return; } - - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)) + "AsNumpy(self):"; - code += OffsetPrefix(field); - - code += Indent + Indent + Indent; - code += "return "; - code += "self._tab.GetVectorAsNumpy(flatbuffers.number_types."; - code += MakeCamel(GenTypeGet(field.value.type)); - code += "Flags, o)\n"; - - if (IsString(vectortype)) { - code += Indent + Indent + "return \"\"\n"; - } else { - code += Indent + Indent + "return 0\n"; - } - code += "\n"; - } - - // Returns a nested flatbuffer as itself. - void GetVectorAsNestedFlatbuffer(const StructDef &struct_def, - const FieldDef &field, - std::string *code_ptr) { - auto nested = field.attributes.Lookup("nested_flatbuffer"); - if (!nested) { return; } // There is no nested flatbuffer. - - std::string unqualified_name = nested->constant; - std::string qualified_name = nested->constant; - auto nested_root = parser_.LookupStruct(nested->constant); - if (nested_root == nullptr) { - qualified_name = - parser_.current_namespace_->GetFullyQualifiedName(nested->constant); - nested_root = parser_.LookupStruct(qualified_name); - } - FLATBUFFERS_ASSERT(nested_root); // Guaranteed to exist by parser. - (void)nested_root; - - auto &code = *code_ptr; - GenReceiver(struct_def, code_ptr); - code += MakeCamel(NormalizedName(field)) + "NestedRoot(self):"; - - code += OffsetPrefix(field); - - code += Indent + Indent + Indent; - code += "from " + qualified_name + " import " + unqualified_name + "\n"; - code += Indent + Indent + Indent + "return " + unqualified_name; - code += ".GetRootAs"; - code += "(self._tab.Bytes, self._tab.Vector(o))\n"; - code += Indent + Indent + "return 0\n"; - code += "\n"; - } - - // Begin the creator function signature. - void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) { - auto &code = *code_ptr; - - code += "\n"; - code += "def Create" + NormalizedName(struct_def); - code += "(builder"; - } - - // Recursively generate arguments for a constructor, to deal with nested - // structs. - void StructBuilderArgs(const StructDef &struct_def, - const std::string nameprefix, - const std::string namesuffix, bool has_field_name, - const std::string fieldname_suffix, - std::string *code_ptr) { - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - const auto &field_type = field.value.type; - const auto &type = - IsArray(field_type) ? field_type.VectorType() : field_type; - if (IsStruct(type)) { - // Generate arguments for a struct inside a struct. To ensure names - // don't clash, and to make it obvious these arguments are constructing - // a nested struct, prefix the name with the field name. - auto subprefix = nameprefix; - if (has_field_name) { - subprefix += NormalizedName(field) + fieldname_suffix; - } - StructBuilderArgs(*field.value.type.struct_def, subprefix, namesuffix, - has_field_name, fieldname_suffix, code_ptr); - } else { - auto &code = *code_ptr; - code += std::string(", ") + nameprefix; - if (has_field_name) { code += MakeCamel(NormalizedName(field), false); } - code += namesuffix; - } - } - } - - // End the creator function signature. - void EndBuilderArgs(std::string *code_ptr) { - auto &code = *code_ptr; - code += "):\n"; - } - - // Recursively generate struct construction statements and instert manual - // padding. - void StructBuilderBody(const StructDef &struct_def, const char *nameprefix, - std::string *code_ptr, size_t index = 0, - bool in_array = false) { - auto &code = *code_ptr; - std::string indent(index * 4, ' '); - code += - indent + " builder.Prep(" + NumToString(struct_def.minalign) + ", "; - code += NumToString(struct_def.bytesize) + ")\n"; - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - const auto &field_type = field.value.type; - const auto &type = - IsArray(field_type) ? field_type.VectorType() : field_type; - if (field.padding) - code += - indent + " builder.Pad(" + NumToString(field.padding) + ")\n"; - if (IsStruct(field_type)) { - StructBuilderBody(*field_type.struct_def, - (nameprefix + (NormalizedName(field) + "_")).c_str(), - code_ptr, index, in_array); - } else { - const auto index_var = "_idx" + NumToString(index); - if (IsArray(field_type)) { - code += indent + " for " + index_var + " in range("; - code += NumToString(field_type.fixed_length); - code += " , 0, -1):\n"; - in_array = true; - } - if (IsStruct(type)) { - StructBuilderBody( - *field_type.struct_def, - (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr, - index + 1, in_array); - } else { - code += IsArray(field_type) ? " " : ""; - code += indent + " builder.Prepend" + GenMethod(field) + "("; - code += nameprefix + MakeCamel(NormalizedName(field), false); - size_t array_cnt = index + (IsArray(field_type) ? 1 : 0); - for (size_t i = 0; in_array && i < array_cnt; i++) { - code += "[_idx" + NumToString(i) + "-1]"; - } - code += ")\n"; - } - } - } - } - - void EndBuilderBody(std::string *code_ptr) { - auto &code = *code_ptr; - code += " return builder.Offset()\n"; - } - - // Get the value of a table's starting offset. - void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) { - auto &code = *code_ptr; - code += "def Start(builder): "; - code += "builder.StartObject("; - code += NumToString(struct_def.fields.vec.size()); - code += ")\n"; - - // Add alias with the old name. - code += "def " + NormalizedName(struct_def) + "Start(builder):\n"; - code += Indent + "\"\"\"This method is deprecated. Please switch to Start.\"\"\"\n"; - code += Indent + "return Start(builder)\n"; - } - - // Set the value of a table's field. - void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field, - const size_t offset, std::string *code_ptr) { - auto &code = *code_ptr; - code += "def Add" + MakeCamel(NormalizedName(field)); - code += "(builder, "; - code += MakeCamel(NormalizedName(field), false); - code += "): "; - code += "builder.Prepend"; - code += GenMethod(field) + "Slot("; - code += NumToString(offset) + ", "; - if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) { - code += "flatbuffers.number_types.UOffsetTFlags.py_type"; - code += "("; - code += MakeCamel(NormalizedName(field), false) + ")"; - } else { - code += MakeCamel(NormalizedName(field), false); - } - code += ", "; - code += IsFloat(field.value.type.base_type) - ? float_const_gen_.GenFloatConstant(field) - : field.value.constant; - code += ")\n"; - - // Add alias with the old name. - code += "def " + NormalizedName(struct_def) + "Add" + MakeCamel(NormalizedName(field)); - code += "(builder, "; - code += MakeCamel(NormalizedName(field), false); - code += "):\n"; - code += Indent + "\"\"\"This method is deprecated. Please switch to Add"; - code += MakeCamel(NormalizedName(field)) + ".\"\"\"\n"; - code += Indent + "return Add" + MakeCamel(NormalizedName(field)); - code += "(builder, "; - code += MakeCamel(NormalizedName(field), false); - code += ")\n"; - - // Add alias with the old name. - } - - // Set the value of one of the members of a table's vector. - void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - code += "def Start"; - code += MakeCamel(NormalizedName(field)); - code += "Vector(builder, numElems): return builder.StartVector("; - auto vector_type = field.value.type.VectorType(); - auto alignment = InlineAlignment(vector_type); - auto elem_size = InlineSize(vector_type); - code += NumToString(elem_size); - code += ", numElems, " + NumToString(alignment); - code += ")\n"; - - // Add alias with the old name. - code += "def " + NormalizedName(struct_def) + "Start"; - code += MakeCamel(NormalizedName(field)); - code += "Vector(builder, numElems):\n"; - code += Indent + "\"\"\"This method is deprecated. Please switch to Start.\"\"\"\n"; - code += Indent + "return Start"; - code += MakeCamel(NormalizedName(field)); - code += "Vector(builder, numElems)\n"; - } - - // Set the value of one of the members of a table's vector and fills in the - // elements from a bytearray. This is for simplifying the use of nested - // flatbuffers. - void BuildVectorOfTableFromBytes(const FieldDef &field, std::string *code_ptr) { - auto nested = field.attributes.Lookup("nested_flatbuffer"); - if (!nested) { return; } // There is no nested flatbuffer. - - std::string unqualified_name = nested->constant; - std::string qualified_name = nested->constant; - auto nested_root = parser_.LookupStruct(nested->constant); - if (nested_root == nullptr) { - qualified_name = - parser_.current_namespace_->GetFullyQualifiedName(nested->constant); - nested_root = parser_.LookupStruct(qualified_name); - } - FLATBUFFERS_ASSERT(nested_root); // Guaranteed to exist by parser. - (void)nested_root; - - auto &code = *code_ptr; - code += "def MakeVectorFromBytes(builder, bytes):\n"; - code += Indent + "builder.StartVector("; - auto vector_type = field.value.type.VectorType(); - auto alignment = InlineAlignment(vector_type); - auto elem_size = InlineSize(vector_type); - code += NumToString(elem_size); - code += ", len(bytes), " + NumToString(alignment); - code += ")\n"; - code += Indent + "builder.head = builder.head - len(bytes)\n"; - code += Indent + "builder.Bytes[builder.head : builder.head + len(bytes)]"; - code += " = bytes\n"; - code += Indent + "return builder.EndVector()\n"; - - // Add alias with the old name. - code += "def Make" + MakeCamel(NormalizedName(field)); - code += "VectorFromBytes(builder, bytes):\n"; - code += Indent + "builder.StartVector("; - code += NumToString(elem_size); - code += ", len(bytes), " + NumToString(alignment); - code += ")\n"; - code += Indent + "builder.head = builder.head - len(bytes)\n"; - code += Indent + "builder.Bytes[builder.head : builder.head + len(bytes)]"; - code += " = bytes\n"; - code += Indent + "return builder.EndVector()\n"; - } - - // Get the offset of the end of a table. - void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) { - auto &code = *code_ptr; - code += "def End(builder): return builder.EndObject()\n"; - - // Add alias with the old name. - code += "def " + NormalizedName(struct_def) + "End(builder):\n"; - code += Indent + "\"\"\"This method is deprecated. Please switch to End.\"\"\"\n"; - code += Indent + "return End(builder)"; - } - - // Generate the receiver for function signatures. - void GenReceiver(const StructDef &struct_def, std::string *code_ptr) { - auto &code = *code_ptr; - code += Indent + "# " + NormalizedName(struct_def) + "\n"; - code += Indent + "def "; - } - - // Generate a struct field, conditioned on its child type(s). - void GenStructAccessor(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str()); - if (IsScalar(field.value.type.base_type)) { - if (struct_def.fixed) { - GetScalarFieldOfStruct(struct_def, field, code_ptr); - } else { - GetScalarFieldOfTable(struct_def, field, code_ptr); - } - } else if (IsArray(field.value.type)) { - GetArrayOfStruct(struct_def, field, code_ptr); - } else { - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: - if (struct_def.fixed) { - GetStructFieldOfStruct(struct_def, field, code_ptr); - } else { - GetStructFieldOfTable(struct_def, field, code_ptr); - } - break; - case BASE_TYPE_STRING: - GetStringField(struct_def, field, code_ptr); - break; - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - if (vectortype.base_type == BASE_TYPE_STRUCT) { - GetMemberOfVectorOfStruct(struct_def, field, code_ptr); - } else { - GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr); - GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr); - GetVectorAsNestedFlatbuffer(struct_def, field, code_ptr); - } - break; - } - case BASE_TYPE_UNION: GetUnionField(struct_def, field, code_ptr); break; - default: FLATBUFFERS_ASSERT(0); - } - } - if (IsVector(field.value.type) || IsArray(field.value.type)) { - GetVectorLen(struct_def, field, code_ptr); - GetVectorIsNone(struct_def, field, code_ptr); - } - } - - // Generate struct sizeof. - void GenStructSizeOf(const StructDef &struct_def, std::string *code_ptr) { - auto &code = *code_ptr; - code += Indent + "@classmethod\n"; - code += Indent + "def SizeOf(cls):\n"; - code += - Indent + Indent + "return " + NumToString(struct_def.bytesize) + "\n"; - code += "\n"; - } - - // Generate table constructors, conditioned on its members' types. - void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) { - GetStartOfTable(struct_def, code_ptr); - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - auto offset = it - struct_def.fields.vec.begin(); - BuildFieldOfTable(struct_def, field, offset, code_ptr); - if (IsVector(field.value.type)) { - BuildVectorOfTable(struct_def, field, code_ptr); - BuildVectorOfTableFromBytes(field, code_ptr); - } - } - - GetEndOffsetOnTable(struct_def, code_ptr); - } - - // Generate function to check for proper file identifier - void GenHasFileIdentifier(const StructDef &struct_def, - std::string *code_ptr) { - auto &code = *code_ptr; - std::string escapedID; - // In the event any of file_identifier characters are special(NULL, \, etc), - // problems occur. To prevent this, convert all chars to their hex-escaped - // equivalent. - for (auto it = parser_.file_identifier_.begin(); - it != parser_.file_identifier_.end(); ++it) { - escapedID += "\\x" + IntToStringHex(*it, 2); - } - - code += Indent + "@classmethod\n"; - code += Indent + "def " + NormalizedName(struct_def); - code += "BufferHasIdentifier(cls, buf, offset, size_prefixed=False):"; - code += "\n"; - code += Indent + Indent; - code += "return flatbuffers.util.BufferHasIdentifier(buf, offset, b\""; - code += escapedID; - code += "\", size_prefixed=size_prefixed)\n"; - code += "\n"; - } - - // Generates struct or table methods. - void GenStruct(const StructDef &struct_def, std::string *code_ptr) { - if (struct_def.generated) return; - - GenComment(struct_def.doc_comment, code_ptr, &def_comment); - BeginClass(struct_def, code_ptr); - if (!struct_def.fixed) { - // Generate a special accessor for the table that has been declared as - // the root type. - NewRootTypeFromBuffer(struct_def, code_ptr); - if (parser_.file_identifier_.length()) { - // Generate a special function to test file_identifier - GenHasFileIdentifier(struct_def, code_ptr); - } - } else { - // Generates the SizeOf method for all structs. - GenStructSizeOf(struct_def, code_ptr); - } - // Generates the Init method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - InitializeExisting(struct_def, code_ptr); - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - GenStructAccessor(struct_def, field, code_ptr); - } - - if (struct_def.fixed) { - // creates a struct constructor function - GenStructBuilder(struct_def, code_ptr); - } else { - // Creates a set of functions that allow table construction. - GenTableBuilders(struct_def, code_ptr); - } - } - - void GenReceiverForObjectAPI(const StructDef &struct_def, - std::string *code_ptr) { - auto &code = *code_ptr; - code += GenIndents(1) + "# " + NormalizedName(struct_def) + "T"; - code += GenIndents(1) + "def "; - } - - void BeginClassForObjectAPI(const StructDef &struct_def, - std::string *code_ptr) { - auto &code = *code_ptr; - code += "\n"; - code += "class " + NormalizedName(struct_def) + "T(object):"; - code += "\n"; - } - - // Gets the accoresponding python builtin type of a BaseType for scalars and - // string. - std::string GetBasePythonTypeForScalarAndString(const BaseType &base_type) { - if (IsBool(base_type)) { - return "bool"; - } else if (IsFloat(base_type)) { - return "float"; - } else if (IsInteger(base_type)) { - return "int"; - } else if (base_type == BASE_TYPE_STRING) { - return "str"; - } else { - FLATBUFFERS_ASSERT(false && "base_type is not a scalar or string type."); - return ""; - } - } - - std::string GetDefaultValue(const FieldDef &field) { - BaseType base_type = field.value.type.base_type; - if (IsBool(base_type)) { - return field.value.constant == "0" ? "False" : "True"; - } else if (IsFloat(base_type)) { - return float_const_gen_.GenFloatConstant(field); - } else if (IsInteger(base_type)) { - return field.value.constant; - } else { - // For string, struct, and table. - return "None"; - } - } - - void GenUnionInit(const FieldDef &field, std::string *field_types_ptr, - std::set<std::string> *import_list, - std::set<std::string> *import_typing_list) { - // Gets all possible types in the union. - import_typing_list->insert("Union"); - auto &field_types = *field_types_ptr; - field_types = "Union["; - - std::string separator_string = ", "; - auto enum_def = field.value.type.enum_def; - for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end(); - ++it) { - auto &ev = **it; - // Union only supports string and table. - std::string field_type; - switch (ev.union_type.base_type) { - case BASE_TYPE_STRUCT: - field_type = GenTypeGet(ev.union_type) + "T"; - if (parser_.opts.include_dependence_headers) { - auto package_reference = GenPackageReference(ev.union_type); - field_type = package_reference + "." + field_type; - 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; - } - field_types += field_type + separator_string; - } - - // Removes the last separator_string. - field_types.erase(field_types.length() - separator_string.size()); - field_types += "]"; - - // Gets the import lists for the union. - if (parser_.opts.include_dependence_headers) { - // The package reference is generated based on enum_def, instead - // of struct_def in field.type. That's why GenPackageReference() is - // not used. - Namespace *namespaces = field.value.type.enum_def->defined_namespace; - auto package_reference = namespaces->GetFullyQualifiedName( - MakeUpperCamel(*(field.value.type.enum_def))); - auto union_name = MakeUpperCamel(*(field.value.type.enum_def)); - import_list->insert("import " + package_reference); - } - } - - void GenStructInit(const FieldDef &field, std::string *field_type_ptr, - std::set<std::string> *import_list, - std::set<std::string> *import_typing_list) { - import_typing_list->insert("Optional"); - auto &field_type = *field_type_ptr; - if (parser_.opts.include_dependence_headers) { - auto package_reference = GenPackageReference(field.value.type); - field_type = package_reference + "." + TypeName(field) + "T]"; - import_list->insert("import " + package_reference); - } else { - field_type = TypeName(field) + "T]"; - } - field_type = "Optional[" + field_type; - } - - void GenVectorInit(const FieldDef &field, std::string *field_type_ptr, - std::set<std::string> *import_list, - std::set<std::string> *import_typing_list) { - import_typing_list->insert("List"); - auto &field_type = *field_type_ptr; - auto base_type = field.value.type.VectorType().base_type; - if (base_type == BASE_TYPE_STRUCT) { - field_type = GenTypeGet(field.value.type.VectorType()) + "T]"; - if (parser_.opts.include_dependence_headers) { - auto package_reference = - GenPackageReference(field.value.type.VectorType()); - field_type = package_reference + "." + - GenTypeGet(field.value.type.VectorType()) + "T]"; - import_list->insert("import " + package_reference); - } - field_type = "List[" + field_type; - } else { - field_type = - "List[" + GetBasePythonTypeForScalarAndString(base_type) + "]"; - } - } - - void GenInitialize(const StructDef &struct_def, std::string *code_ptr, - std::set<std::string> *import_list) { - std::string code; - std::set<std::string> import_typing_list; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - // Determines field type, default value, and typing imports. - auto base_type = field.value.type.base_type; - std::string field_type; - switch (base_type) { - case BASE_TYPE_UNION: { - GenUnionInit(field, &field_type, import_list, &import_typing_list); - break; - } - case BASE_TYPE_STRUCT: { - GenStructInit(field, &field_type, import_list, &import_typing_list); - break; - } - case BASE_TYPE_VECTOR: - case BASE_TYPE_ARRAY: { - GenVectorInit(field, &field_type, import_list, &import_typing_list); - break; - } - default: - // Scalar or sting fields. - field_type = GetBasePythonTypeForScalarAndString(base_type); - break; - } - - auto default_value = GetDefaultValue(field); - // Wrties the init statement. - auto field_instance_name = MakeLowerCamel(field); - code += GenIndents(2) + "self." + field_instance_name + " = " + - default_value + " # type: " + field_type; - } - - // Writes __init__ method. - auto &code_base = *code_ptr; - GenReceiverForObjectAPI(struct_def, code_ptr); - code_base += "__init__(self):"; - if (code.empty()) { - code_base += GenIndents(2) + "pass"; - } else { - code_base += code; - } - code_base += "\n"; - - // Merges the typing imports into import_list. - if (!import_typing_list.empty()) { - // Adds the try statement. - std::string typing_imports = "try:"; - typing_imports += GenIndents(1) + "from typing import "; - std::string separator_string = ", "; - for (auto it = import_typing_list.begin(); it != import_typing_list.end(); - ++it) { - const std::string &im = *it; - typing_imports += im + separator_string; - } - // Removes the last separator_string. - typing_imports.erase(typing_imports.length() - separator_string.size()); - - // Adds the except statement. - typing_imports += "\n"; - typing_imports += "except:"; - typing_imports += GenIndents(1) + "pass"; - import_list->insert(typing_imports); - } - - // Removes the import of the struct itself, if applied. - auto package_reference = - struct_def.defined_namespace->GetFullyQualifiedName( - MakeUpperCamel(struct_def)); - auto struct_import = "import " + package_reference; - import_list->erase(struct_import); - } - - void InitializeFromBuf(const StructDef &struct_def, std::string *code_ptr) { - auto &code = *code_ptr; - auto instance_name = MakeLowerCamel(struct_def); - auto struct_name = NormalizedName(struct_def); - - code += GenIndents(1) + "@classmethod"; - code += GenIndents(1) + "def InitFromBuf(cls, buf, pos):"; - code += GenIndents(2) + instance_name + " = " + struct_name + "()"; - code += GenIndents(2) + instance_name + ".Init(buf, pos)"; - code += GenIndents(2) + "return cls.InitFromObj(" + instance_name + ")"; - code += "\n"; - } - - void InitializeFromObjForObject(const StructDef &struct_def, - std::string *code_ptr) { - auto &code = *code_ptr; - auto instance_name = MakeLowerCamel(struct_def); - auto struct_name = NormalizedName(struct_def); - - code += GenIndents(1) + "@classmethod"; - code += GenIndents(1) + "def InitFromObj(cls, " + instance_name + "):"; - code += GenIndents(2) + "x = " + struct_name + "T()"; - code += GenIndents(2) + "x._UnPack(" + instance_name + ")"; - code += GenIndents(2) + "return x"; - code += "\n"; - } - - void GenUnPackForStruct(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - auto struct_instance_name = MakeLowerCamel(struct_def); - auto field_instance_name = MakeLowerCamel(field); - auto field_accessor_name = MakeUpperCamel(field); - auto field_type = TypeName(field); - - if (parser_.opts.include_dependence_headers) { - auto package_reference = GenPackageReference(field.value.type); - field_type = package_reference + "." + TypeName(field); - } - - code += GenIndents(2) + "if " + struct_instance_name + "." + - field_accessor_name + "("; - // if field is a struct, we need to create an instance for it first. - if (struct_def.fixed && field.value.type.base_type == BASE_TYPE_STRUCT) { - code += field_type + "()"; - } - code += ") is not None:"; - code += GenIndents(3) + "self." + field_instance_name + " = " + field_type + - "T.InitFromObj(" + struct_instance_name + "." + - field_accessor_name + "("; - // A struct's accessor requires a struct buf instance. - if (struct_def.fixed && field.value.type.base_type == BASE_TYPE_STRUCT) { - code += field_type + "()"; - } - code += "))"; - } - - void GenUnPackForUnion(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - auto field_instance_name = MakeLowerCamel(field); - auto field_accessor_name = MakeUpperCamel(field); - auto struct_instance_name = MakeLowerCamel(struct_def); - auto union_name = MakeUpperCamel(*(field.value.type.enum_def)); - - if (parser_.opts.include_dependence_headers) { - Namespace *namespaces = field.value.type.enum_def->defined_namespace; - auto package_reference = namespaces->GetFullyQualifiedName( - MakeUpperCamel(*(field.value.type.enum_def))); - union_name = package_reference + "." + union_name; - } - code += GenIndents(2) + "self." + field_instance_name + " = " + union_name + - "Creator(" + "self." + field_instance_name + "Type, " + - struct_instance_name + "." + field_accessor_name + "())"; - } - - void GenUnPackForStructVector(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - auto &code = *code_ptr; - auto field_instance_name = MakeLowerCamel(field); - auto field_accessor_name = MakeUpperCamel(field); - auto struct_instance_name = MakeLowerCamel(struct_def); - - code += GenIndents(2) + "if not " + struct_instance_name + "." + - field_accessor_name + "IsNone():"; - code += GenIndents(3) + "self." + field_instance_name + " = []"; - code += GenIndents(3) + "for i in range(" + struct_instance_name + "." + - field_accessor_name + "Length()):"; - - auto field_type_name = TypeName(field); - auto one_instance = field_type_name + "_"; - one_instance[0] = CharToLower(one_instance[0]); - - if (parser_.opts.include_dependence_headers) { - auto package_reference = GenPackageReference(field.value.type); - field_type_name = package_reference + "." + TypeName(field); - } - - code += GenIndents(4) + "if " + struct_instance_name + "." + - field_accessor_name + "(i) is None:"; - code += GenIndents(5) + "self." + field_instance_name + ".append(None)"; - code += GenIndents(4) + "else:"; - code += GenIndents(5) + one_instance + " = " + field_type_name + - "T.InitFromObj(" + struct_instance_name + "." + - field_accessor_name + "(i))"; - code += GenIndents(5) + "self." + field_instance_name + ".append(" + - one_instance + ")"; - } - - void GenUnpackforScalarVectorHelper(const StructDef &struct_def, - const FieldDef &field, - std::string *code_ptr, int indents) { - auto &code = *code_ptr; - auto field_instance_name = MakeLowerCamel(field); - auto field_accessor_name = MakeUpperCamel(field); - auto struct_instance_name = MakeLowerCamel(struct_def); - - code += GenIndents(indents) + "self." + field_instance_name + " = []"; - code += GenIndents(indents) + "for i in range(" + struct_instance_name + - "." + field_accessor_name + "Length()):"; - code += GenIndents(indents + 1) + "self." + field_instance_name + - ".append(" + struct_instance_name + "." + field_accessor_name + - "(i))"; - } - - void GenUnPackForScalarVector(const StructDef &struct_def, - const FieldDef &field, std::string *code_ptr) { - auto &code = *code_ptr; - auto field_instance_name = MakeLowerCamel(field); - auto field_accessor_name = MakeUpperCamel(field); - auto struct_instance_name = MakeLowerCamel(struct_def); - - code += GenIndents(2) + "if not " + struct_instance_name + "." + - field_accessor_name + "IsNone():"; - - // String does not have the AsNumpy method. - if (!(IsScalar(field.value.type.VectorType().base_type))) { - GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 3); - return; - } - - code += GenIndents(3) + "if np is None:"; - GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 4); - - // If numpy exists, use the AsNumpy method to optimize the unpack speed. - code += GenIndents(3) + "else:"; - code += GenIndents(4) + "self." + field_instance_name + " = " + - struct_instance_name + "." + field_accessor_name + "AsNumpy()"; - } - - void GenUnPackForScalar(const StructDef &struct_def, const FieldDef &field, - std::string *code_ptr) { - auto &code = *code_ptr; - auto field_instance_name = MakeLowerCamel(field); - auto field_accessor_name = MakeUpperCamel(field); - auto struct_instance_name = MakeLowerCamel(struct_def); - - code += GenIndents(2) + "self." + field_instance_name + " = " + - struct_instance_name + "." + field_accessor_name + "()"; - } - - // Generates the UnPack method for the object class. - void GenUnPack(const StructDef &struct_def, std::string *code_ptr) { - std::string code; - // Items that needs to be imported. No duplicate modules will be imported. - std::set<std::string> import_list; - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - auto field_type = TypeName(field); - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - GenUnPackForStruct(struct_def, field, &code); - break; - } - case BASE_TYPE_UNION: { - GenUnPackForUnion(struct_def, field, &code); - break; - } - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - if (vectortype.base_type == BASE_TYPE_STRUCT) { - GenUnPackForStructVector(struct_def, field, &code); - } else { - GenUnPackForScalarVector(struct_def, field, &code); - } - break; - } - case BASE_TYPE_ARRAY: { - GenUnPackForScalarVector(struct_def, field, &code); - break; - } - default: GenUnPackForScalar(struct_def, field, &code); - } - } - - // Writes import statements and code into the generated file. - auto &code_base = *code_ptr; - auto struct_instance_name = MakeLowerCamel(struct_def); - auto struct_name = MakeUpperCamel(struct_def); - - GenReceiverForObjectAPI(struct_def, code_ptr); - code_base += "_UnPack(self, " + struct_instance_name + "):"; - code_base += GenIndents(2) + "if " + struct_instance_name + " is None:"; - code_base += GenIndents(3) + "return"; - - // Write the import statements. - for (std::set<std::string>::iterator it = import_list.begin(); - it != import_list.end(); ++it) { - code_base += GenIndents(2) + *it; - } - - // Write the code. - code_base += code; - code_base += "\n"; - } - - void GenPackForStruct(const StructDef &struct_def, std::string *code_ptr) { - auto &code = *code_ptr; - auto struct_name = MakeUpperCamel(struct_def); - - GenReceiverForObjectAPI(struct_def, code_ptr); - code += "Pack(self, builder):"; - code += GenIndents(2) + "return Create" + struct_name + "(builder"; - - StructBuilderArgs(struct_def, - /* nameprefix = */ "self.", - /* namesuffix = */ "", - /* has_field_name = */ true, - /* fieldname_suffix = */ ".", code_ptr); - code += ")\n"; - } - - void GenPackForStructVectorField(const StructDef &struct_def, - const FieldDef &field, - std::string *code_prefix_ptr, - std::string *code_ptr) { - auto &code_prefix = *code_prefix_ptr; - auto &code = *code_ptr; - auto field_instance_name = MakeLowerCamel(field); - auto struct_name = NormalizedName(struct_def); - auto field_accessor_name = MakeUpperCamel(field); - - // Creates the field. - code_prefix += - GenIndents(2) + "if self." + field_instance_name + " is not None:"; - if (field.value.type.struct_def->fixed) { - code_prefix += GenIndents(3) + "Start" + - field_accessor_name + "Vector(builder, len(self." + - field_instance_name + "))"; - code_prefix += GenIndents(3) + "for i in reversed(range(len(self." + - field_instance_name + "))):"; - code_prefix += - GenIndents(4) + "self." + field_instance_name + "[i].Pack(builder)"; - code_prefix += - GenIndents(3) + field_instance_name + " = builder.EndVector()"; - } else { - // If the vector is a struct vector, we need to first build accessor for - // each struct element. - code_prefix += GenIndents(3) + field_instance_name + "list = []"; - code_prefix += GenIndents(3); - code_prefix += "for i in range(len(self." + field_instance_name + ")):"; - code_prefix += GenIndents(4) + field_instance_name + "list.append(self." + - field_instance_name + "[i].Pack(builder))"; - - code_prefix += GenIndents(3) + "Start" + - field_accessor_name + "Vector(builder, len(self." + - field_instance_name + "))"; - code_prefix += GenIndents(3) + "for i in reversed(range(len(self." + - field_instance_name + "))):"; - code_prefix += GenIndents(4) + "builder.PrependUOffsetTRelative" + "(" + - field_instance_name + "list[i])"; - code_prefix += - GenIndents(3) + field_instance_name + " = builder.EndVector()"; - } - - // Adds the field into the struct. - code += GenIndents(2) + "if self." + field_instance_name + " is not None:"; - code += GenIndents(3) + "Add" + field_accessor_name + - "(builder, " + field_instance_name + ")"; - } - - void GenPackForScalarVectorFieldHelper(const StructDef &struct_def, - const FieldDef &field, - std::string *code_ptr, int indents) { - auto &code = *code_ptr; - auto field_instance_name = MakeLowerCamel(field); - auto field_accessor_name = MakeUpperCamel(field); - auto struct_name = NormalizedName(struct_def); - auto vectortype = field.value.type.VectorType(); - - code += GenIndents(indents) + "Start" + field_accessor_name + - "Vector(builder, len(self." + field_instance_name + "))"; - code += GenIndents(indents) + "for i in reversed(range(len(self." + - field_instance_name + "))):"; - code += GenIndents(indents + 1) + "builder.Prepend"; - - std::string type_name; - switch (vectortype.base_type) { - case BASE_TYPE_BOOL: type_name = "Bool"; break; - case BASE_TYPE_CHAR: type_name = "Byte"; break; - case BASE_TYPE_UCHAR: type_name = "Uint8"; break; - case BASE_TYPE_SHORT: type_name = "Int16"; break; - case BASE_TYPE_USHORT: type_name = "Uint16"; break; - case BASE_TYPE_INT: type_name = "Int32"; break; - case BASE_TYPE_UINT: type_name = "Uint32"; break; - case BASE_TYPE_LONG: type_name = "Int64"; break; - case BASE_TYPE_ULONG: type_name = "Uint64"; break; - case BASE_TYPE_FLOAT: type_name = "Float32"; break; - case BASE_TYPE_DOUBLE: type_name = "Float64"; break; - case BASE_TYPE_STRING: type_name = "UOffsetTRelative"; break; - default: type_name = "VOffsetT"; break; - } - code += type_name; - } - - void GenPackForScalarVectorField(const StructDef &struct_def, - const FieldDef &field, - std::string *code_prefix_ptr, - std::string *code_ptr) { - auto &code = *code_ptr; - auto &code_prefix = *code_prefix_ptr; - auto field_instance_name = MakeLowerCamel(field); - auto field_accessor_name = MakeUpperCamel(field); - auto struct_name = NormalizedName(struct_def); - - // Adds the field into the struct. - code += GenIndents(2) + "if self." + field_instance_name + " is not None:"; - code += GenIndents(3) + "Add" + field_accessor_name + - "(builder, " + field_instance_name + ")"; - - // Creates the field. - code_prefix += - GenIndents(2) + "if self." + field_instance_name + " is not None:"; - // If the vector is a string vector, we need to first build accessor for - // each string element. And this generated code, needs to be - // placed ahead of code_prefix. - auto vectortype = field.value.type.VectorType(); - if (IsString(vectortype)) { - code_prefix += GenIndents(3) + MakeLowerCamel(field) + "list = []"; - code_prefix += GenIndents(3) + "for i in range(len(self." + - field_instance_name + ")):"; - code_prefix += GenIndents(4) + MakeLowerCamel(field) + - "list.append(builder.CreateString(self." + - field_instance_name + "[i]))"; - GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 3); - code_prefix += "(" + MakeLowerCamel(field) + "list[i])"; - code_prefix += - GenIndents(3) + field_instance_name + " = builder.EndVector()"; - return; - } - - code_prefix += GenIndents(3) + "if np is not None and type(self." + - field_instance_name + ") is np.ndarray:"; - code_prefix += GenIndents(4) + field_instance_name + - " = builder.CreateNumpyVector(self." + field_instance_name + - ")"; - code_prefix += GenIndents(3) + "else:"; - GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 4); - code_prefix += "(self." + field_instance_name + "[i])"; - code_prefix += - GenIndents(4) + field_instance_name + " = builder.EndVector()"; - } - - void GenPackForStructField(const StructDef &struct_def, const FieldDef &field, - std::string *code_prefix_ptr, - std::string *code_ptr) { - auto &code_prefix = *code_prefix_ptr; - auto &code = *code_ptr; - auto field_instance_name = MakeLowerCamel(field); - - auto field_accessor_name = MakeUpperCamel(field); - auto struct_name = NormalizedName(struct_def); - - if (field.value.type.struct_def->fixed) { - // Pure struct fields need to be created along with their parent - // structs. - code += - GenIndents(2) + "if self." + field_instance_name + " is not None:"; - code += GenIndents(3) + field_instance_name + " = self." + - field_instance_name + ".Pack(builder)"; - } else { - // Tables need to be created before their parent structs are created. - code_prefix += - GenIndents(2) + "if self." + field_instance_name + " is not None:"; - code_prefix += GenIndents(3) + field_instance_name + " = self." + - field_instance_name + ".Pack(builder)"; - code += - GenIndents(2) + "if self." + field_instance_name + " is not None:"; - } - - code += GenIndents(3) + "Add" + field_accessor_name + - "(builder, " + field_instance_name + ")"; - } - - void GenPackForUnionField(const StructDef &struct_def, const FieldDef &field, - std::string *code_prefix_ptr, - std::string *code_ptr) { - auto &code_prefix = *code_prefix_ptr; - auto &code = *code_ptr; - auto field_instance_name = MakeLowerCamel(field); - - auto field_accessor_name = MakeUpperCamel(field); - auto struct_name = NormalizedName(struct_def); - - // TODO(luwa): TypeT should be moved under the None check as well. - code_prefix += - GenIndents(2) + "if self." + field_instance_name + " is not None:"; - code_prefix += GenIndents(3) + field_instance_name + " = self." + - field_instance_name + ".Pack(builder)"; - code += GenIndents(2) + "if self." + field_instance_name + " is not None:"; - code += GenIndents(3) + "Add" + field_accessor_name + - "(builder, " + field_instance_name + ")"; - } - - void GenPackForTable(const StructDef &struct_def, std::string *code_ptr) { - auto &code_base = *code_ptr; - std::string code, code_prefix; - auto struct_instance_name = MakeLowerCamel(struct_def); - auto struct_name = NormalizedName(struct_def); - - GenReceiverForObjectAPI(struct_def, code_ptr); - code_base += "Pack(self, builder):"; - code += GenIndents(2) + "Start(builder)"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - auto field_accessor_name = MakeUpperCamel(field); - auto field_instance_name = MakeLowerCamel(field); - - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - GenPackForStructField(struct_def, field, &code_prefix, &code); - break; - } - case BASE_TYPE_UNION: { - GenPackForUnionField(struct_def, field, &code_prefix, &code); - break; - } - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - if (vectortype.base_type == BASE_TYPE_STRUCT) { - GenPackForStructVectorField(struct_def, field, &code_prefix, &code); - } else { - GenPackForScalarVectorField(struct_def, field, &code_prefix, &code); - } - break; - } - case BASE_TYPE_ARRAY: { - GenPackForScalarVectorField(struct_def, field, &code_prefix, &code); - break; - } - case BASE_TYPE_STRING: { - code_prefix += GenIndents(2) + "if self." + field_instance_name + - " is not None:"; - code_prefix += GenIndents(3) + field_instance_name + - " = builder.CreateString(self." + field_instance_name + - ")"; - code += GenIndents(2) + "if self." + field_instance_name + - " is not None:"; - code += GenIndents(3) + "Add" + field_accessor_name + - "(builder, " + field_instance_name + ")"; - break; - } - default: - // Generates code for scalar values. If the value equals to the - // default value, builder will automatically ignore it. So we don't - // need to check the value ahead. - code += GenIndents(2) + "Add" + field_accessor_name + - "(builder, self." + field_instance_name + ")"; - break; - } - } - - code += GenIndents(2) + struct_instance_name + " = " + "End(builder)"; - code += GenIndents(2) + "return " + struct_instance_name; - - code_base += code_prefix + code; - code_base += "\n"; - } - - void GenStructForObjectAPI(const StructDef &struct_def, - std::string *code_ptr) { - if (struct_def.generated) return; - - std::set<std::string> import_list; - std::string code; - - // Creates an object class for a struct or a table - BeginClassForObjectAPI(struct_def, &code); - - GenInitialize(struct_def, &code, &import_list); - - InitializeFromBuf(struct_def, &code); - - InitializeFromObjForObject(struct_def, &code); - - GenUnPack(struct_def, &code); - - if (struct_def.fixed) { - GenPackForStruct(struct_def, &code); - } else { - GenPackForTable(struct_def, &code); - } - - // Adds the imports at top. - auto &code_base = *code_ptr; - code_base += "\n"; - for (auto it = import_list.begin(); it != import_list.end(); it++) { - auto im = *it; - code_base += im + "\n"; - } - code_base += code; - } - - void GenUnionCreatorForStruct(const EnumDef &enum_def, const EnumVal &ev, - std::string *code_ptr) { - auto &code = *code_ptr; - auto union_name = NormalizedName(enum_def); - auto field_name = NormalizedName(ev); - auto field_type = GenTypeGet(ev.union_type) + "T"; - - code += GenIndents(1) + "if unionType == " + union_name + "()." + - field_name + ":"; - if (parser_.opts.include_dependence_headers) { - auto package_reference = GenPackageReference(ev.union_type); - code += GenIndents(2) + "import " + package_reference; - field_type = package_reference + "." + field_type; - } - code += GenIndents(2) + "return " + field_type + - ".InitFromBuf(table.Bytes, table.Pos)"; - } - - void GenUnionCreatorForString(const EnumDef &enum_def, const EnumVal &ev, - std::string *code_ptr) { - auto &code = *code_ptr; - auto union_name = NormalizedName(enum_def); - auto field_name = NormalizedName(ev); - - code += GenIndents(1) + "if unionType == " + union_name + "()." + - field_name + ":"; - code += GenIndents(2) + "tab = Table(table.Bytes, table.Pos)"; - code += GenIndents(2) + "union = tab.String(table.Pos)"; - code += GenIndents(2) + "return union"; - } - - // Creates an union object based on union type. - void GenUnionCreator(const EnumDef &enum_def, std::string *code_ptr) { - auto &code = *code_ptr; - auto union_name = MakeUpperCamel(enum_def); - - code += "\n"; - code += "def " + union_name + "Creator(unionType, table):"; - code += GenIndents(1) + "from flatbuffers.table import Table"; - code += GenIndents(1) + "if not isinstance(table, Table):"; - code += GenIndents(2) + "return None"; - - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - // Union only supports string and table. - switch (ev.union_type.base_type) { - case BASE_TYPE_STRUCT: - GenUnionCreatorForStruct(enum_def, ev, &code); - break; - case BASE_TYPE_STRING: - GenUnionCreatorForString(enum_def, ev, &code); - break; - default: break; - } - } - code += GenIndents(1) + "return None"; - code += "\n"; - } - - // Generate enum declarations. - void GenEnum(const EnumDef &enum_def, std::string *code_ptr) { - if (enum_def.generated) return; - - GenComment(enum_def.doc_comment, code_ptr, &def_comment); - BeginEnum(NormalizedName(enum_def), code_ptr); - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - GenComment(ev.doc_comment, code_ptr, &def_comment, Indent.c_str()); - EnumMember(enum_def, ev, code_ptr); - } - EndEnum(code_ptr); - } - - // Returns the function name that is able to read a value of the given type. - std::string GenGetter(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_STRING: return "self._tab.String("; - case BASE_TYPE_UNION: return "self._tab.Union("; - case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); - default: - return "self._tab.Get(flatbuffers.number_types." + - MakeCamel(GenTypeGet(type)) + "Flags, "; - } - } - - // Returns the method name for use with add/put calls. - std::string GenMethod(const FieldDef &field) { - return (IsScalar(field.value.type.base_type) || IsArray(field.value.type)) - ? MakeCamel(GenTypeBasic(field.value.type)) - : (IsStruct(field.value.type) ? "Struct" : "UOffsetTRelative"); - } - - std::string GenTypeBasic(const Type &type) { - // clang-format off - static const char *ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \ - #PTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - return ctypename[IsArray(type) ? type.VectorType().base_type - : type.base_type]; - } - - std::string GenTypePointer(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_STRING: return "string"; - case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); - case BASE_TYPE_STRUCT: return type.struct_def->name; - case BASE_TYPE_UNION: - // fall through - default: return "*flatbuffers.Table"; - } - } - - std::string GenTypeGet(const Type &type) { - return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type); - } - - std::string TypeName(const FieldDef &field) { - return GenTypeGet(field.value.type); - } - - // Create a struct with a builder and the struct's arguments. - void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) { - BeginBuilderArgs(struct_def, code_ptr); - StructBuilderArgs(struct_def, - /* nameprefix = */ "", - /* namesuffix = */ "", - /* has_field_name = */ true, - /* fieldname_suffix = */ "_", code_ptr); - EndBuilderArgs(code_ptr); - - StructBuilderBody(struct_def, "", code_ptr); - EndBuilderBody(code_ptr); - } - - bool generate() { - if (!generateEnums()) return false; - if (!generateStructs()) return false; - return true; - } - - private: - bool generateEnums() { - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - auto &enum_def = **it; - std::string enumcode; - GenEnum(enum_def, &enumcode); - if (parser_.opts.generate_object_based_api & enum_def.is_union) { - GenUnionCreator(enum_def, &enumcode); - } - if (!SaveType(enum_def, enumcode, false)) return false; - } - return true; - } - - bool generateStructs() { - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - auto &struct_def = **it; - std::string declcode; - GenStruct(struct_def, &declcode); - if (parser_.opts.generate_object_based_api) { - GenStructForObjectAPI(struct_def, &declcode); - } - if (!SaveType(struct_def, declcode, true)) return false; - } - return true; - } - - // Begin by declaring namespace and imports. - void BeginFile(const std::string &name_space_name, const bool needs_imports, - std::string *code_ptr) { - auto &code = *code_ptr; - code = code + "# " + FlatBuffersGeneratedWarning() + "\n\n"; - code += "# namespace: " + name_space_name + "\n\n"; - if (needs_imports) { - code += "import flatbuffers\n"; - code += "from flatbuffers.compat import import_numpy\n"; - code += "np = import_numpy()\n\n"; - } - } - - // Save out the generated code for a Python Table type. - bool SaveType(const Definition &def, const std::string &classcode, - bool needs_imports) { - if (!classcode.length()) return true; - - std::string namespace_dir = path_; - auto &namespaces = def.defined_namespace->components; - for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { - if (it != namespaces.begin()) namespace_dir += kPathSeparator; - namespace_dir += *it; - std::string init_py_filename = namespace_dir + "/__init__.py"; - SaveFile(init_py_filename.c_str(), "", false); - } - - std::string code = ""; - BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code); - code += classcode; - std::string filename = - NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py"; - return SaveFile(filename.c_str(), code, false); - } - - private: - std::unordered_set<std::string> keywords_; - const SimpleFloatConstantGenerator float_const_gen_; -}; - -} // namespace python - -bool GeneratePython(const Parser &parser, const std::string &path, - const std::string &file_name) { - python::PythonGenerator generator(parser, path, file_name); - return generator.generate(); -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_rust.cpp b/contrib/libs/flatbuffers/src/idl_gen_rust.cpp deleted file mode 100644 index 455780cd94..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_rust.cpp +++ /dev/null @@ -1,2817 +0,0 @@ -/* - * Copyright 2018 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -// Convert a camelCaseIdentifier or CamelCaseIdentifier to a -// snake_case_identifier. -std::string MakeSnakeCase(const std::string &in) { - std::string s; - for (size_t i = 0; i < in.length(); i++) { - if (i == 0) { - s += CharToLower(in[0]); - } else if (in[i] == '_') { - s += '_'; - } else if (!islower(in[i])) { - // Prevent duplicate underscores for Upper_Snake_Case strings - // and UPPERCASE strings. - if (islower(in[i - 1])) { s += '_'; } - s += CharToLower(in[i]); - } else { - s += in[i]; - } - } - return s; -} - -// Convert a string to all uppercase. -std::string MakeUpper(const std::string &in) { - std::string s; - for (size_t i = 0; i < in.length(); i++) { s += CharToUpper(in[i]); } - return s; -} - -// Encapsulate all logical field types in this enum. This allows us to write -// field logic based on type switches, instead of branches on the properties -// set on the Type. -// TODO(rw): for backwards compatibility, we can't use a strict `enum class` -// declaration here. could we use the `-Wswitch-enum` warning to -// achieve the same effect? -enum FullType { - ftInteger = 0, - ftFloat = 1, - ftBool = 2, - - ftStruct = 3, - ftTable = 4, - - ftEnumKey = 5, - ftUnionKey = 6, - - ftUnionValue = 7, - - // TODO(rw): bytestring? - ftString = 8, - - ftVectorOfInteger = 9, - ftVectorOfFloat = 10, - ftVectorOfBool = 11, - ftVectorOfEnumKey = 12, - ftVectorOfStruct = 13, - ftVectorOfTable = 14, - ftVectorOfString = 15, - ftVectorOfUnionValue = 16, - - ftArrayOfBuiltin = 17, - ftArrayOfEnum = 18, - ftArrayOfStruct = 19, -}; - -// Convert a Type to a FullType (exhaustive). -FullType GetFullType(const Type &type) { - // N.B. The order of these conditionals matters for some types. - - if (IsString(type)) { - return ftString; - } else if (type.base_type == BASE_TYPE_STRUCT) { - if (type.struct_def->fixed) { - return ftStruct; - } else { - return ftTable; - } - } else if (IsVector(type)) { - switch (GetFullType(type.VectorType())) { - case ftInteger: { - return ftVectorOfInteger; - } - case ftFloat: { - return ftVectorOfFloat; - } - case ftBool: { - return ftVectorOfBool; - } - case ftStruct: { - return ftVectorOfStruct; - } - case ftTable: { - return ftVectorOfTable; - } - case ftString: { - return ftVectorOfString; - } - case ftEnumKey: { - return ftVectorOfEnumKey; - } - case ftUnionKey: - case ftUnionValue: { - FLATBUFFERS_ASSERT(false && "vectors of unions are unsupported"); - break; - } - default: { - FLATBUFFERS_ASSERT(false && "vector of vectors are unsupported"); - } - } - } else if (IsArray(type)) { - switch (GetFullType(type.VectorType())) { - case ftInteger: - case ftFloat: - case ftBool: { - return ftArrayOfBuiltin; - } - case ftStruct: { - return ftArrayOfStruct; - } - case ftEnumKey: { - return ftArrayOfEnum; - } - default: { - FLATBUFFERS_ASSERT(false && "Unsupported type for fixed array"); - } - } - } else if (type.enum_def != nullptr) { - if (type.enum_def->is_union) { - if (type.base_type == BASE_TYPE_UNION) { - return ftUnionValue; - } else if (IsInteger(type.base_type)) { - return ftUnionKey; - } else { - FLATBUFFERS_ASSERT(false && "unknown union field type"); - } - } else { - return ftEnumKey; - } - } else if (IsScalar(type.base_type)) { - if (IsBool(type.base_type)) { - return ftBool; - } else if (IsInteger(type.base_type)) { - return ftInteger; - } else if (IsFloat(type.base_type)) { - return ftFloat; - } else { - FLATBUFFERS_ASSERT(false && "unknown number type"); - } - } - - FLATBUFFERS_ASSERT(false && "completely unknown type"); - - // this is only to satisfy the compiler's return analysis. - return ftBool; -} - -// If the second parameter is false then wrap the first with Option<...> -std::string WrapInOptionIfNotRequired(std::string s, bool required) { - if (required) { - return s; - } else { - return "Option<" + s + ">"; - } -} - -// If the second parameter is false then add .unwrap() -std::string AddUnwrapIfRequired(std::string s, bool required) { - if (required) { - return s + ".unwrap()"; - } else { - return s; - } -} - -bool IsBitFlagsEnum(const EnumDef &enum_def) { - return enum_def.attributes.Lookup("bit_flags") != nullptr; -} -bool IsBitFlagsEnum(const FieldDef &field) { - EnumDef *ed = field.value.type.enum_def; - return ed && IsBitFlagsEnum(*ed); -} - -// TableArgs make required non-scalars "Option<_>". -// TODO(cneo): Rework how we do defaults and stuff. -bool IsOptionalToBuilder(const FieldDef &field) { - return field.IsOptional() || !IsScalar(field.value.type.base_type); -} - -namespace rust { - -class RustGenerator : public BaseGenerator { - public: - RustGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", "::", "rs"), - cur_name_space_(nullptr) { - const char *keywords[] = { - // clang-format off - // list taken from: - // https://doc.rust-lang.org/book/second-edition/appendix-01-keywords.html - // - // we write keywords one per line so that we can easily compare them with - // changes to that webpage in the future. - - // currently-used keywords - "as", - "break", - "const", - "continue", - "crate", - "else", - "enum", - "extern", - "false", - "fn", - "for", - "if", - "impl", - "in", - "let", - "loop", - "match", - "mod", - "move", - "mut", - "pub", - "ref", - "return", - "Self", - "self", - "static", - "struct", - "super", - "trait", - "true", - "type", - "unsafe", - "use", - "where", - "while", - - // future possible keywords - "abstract", - "alignof", - "become", - "box", - "do", - "final", - "macro", - "offsetof", - "override", - "priv", - "proc", - "pure", - "sizeof", - "typeof", - "unsized", - "virtual", - "yield", - - // other rust terms we should not use - "std", - "usize", - "isize", - "u8", - "i8", - "u16", - "i16", - "u32", - "i32", - "u64", - "i64", - "u128", - "i128", - "f32", - "f64", - - // These are terms the code generator can implement on types. - // - // In Rust, the trait resolution rules (as described at - // https://github.com/rust-lang/rust/issues/26007) mean that, as long - // as we impl table accessors as inherent methods, we'll never create - // conflicts with these keywords. However, that's a fairly nuanced - // implementation detail, and how we implement methods could change in - // the future. as a result, we proactively block these out as reserved - // words. - "follow", - "push", - "size", - "alignment", - "to_little_endian", - "from_little_endian", - nullptr, - - // used by Enum constants - "ENUM_MAX", - "ENUM_MIN", - "ENUM_VALUES", - }; - for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw); - } - - // Iterate through all definitions we haven't generated code for (enums, - // structs, and tables) and output them to a single file. - bool generate() { - code_.Clear(); - code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; - - assert(!cur_name_space_); - - // Generate imports for the global scope in case no namespace is used - // in the schema file. - GenNamespaceImports(0); - code_ += ""; - - // Generate all code in their namespaces, once, because Rust does not - // permit re-opening modules. - // - // TODO(rw): Use a set data structure to reduce namespace evaluations from - // O(n**2) to O(n). - for (auto ns_it = parser_.namespaces_.begin(); - ns_it != parser_.namespaces_.end(); ++ns_it) { - const auto &ns = *ns_it; - - // Generate code for all the enum declarations. - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - const auto &enum_def = **it; - if (enum_def.defined_namespace == ns && !enum_def.generated) { - SetNameSpace(enum_def.defined_namespace); - GenEnum(enum_def); - } - } - - // Generate code for all structs. - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (struct_def.defined_namespace == ns && struct_def.fixed && - !struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - GenStruct(struct_def); - } - } - - // Generate code for all tables. - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (struct_def.defined_namespace == ns && !struct_def.fixed && - !struct_def.generated) { - SetNameSpace(struct_def.defined_namespace); - GenTable(struct_def); - if (parser_.opts.generate_object_based_api) { - GenTableObject(struct_def); - } - } - } - - // Generate global helper functions. - if (parser_.root_struct_def_) { - auto &struct_def = *parser_.root_struct_def_; - if (struct_def.defined_namespace != ns) { continue; } - SetNameSpace(struct_def.defined_namespace); - GenRootTableFuncs(struct_def); - } - } - if (cur_name_space_) SetNameSpace(nullptr); - - const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts); - const auto final_code = code_.ToString(); - return SaveFile(file_path.c_str(), final_code, false); - } - - private: - CodeWriter code_; - - std::set<std::string> keywords_; - - // This tracks the current namespace so we can insert namespace declarations. - const Namespace *cur_name_space_; - - const Namespace *CurrentNameSpace() const { return cur_name_space_; } - - // Determine if a Type needs a lifetime template parameter when used in the - // Rust builder args. - bool TableBuilderTypeNeedsLifetime(const Type &type) const { - switch (GetFullType(type)) { - case ftInteger: - case ftFloat: - case ftBool: - case ftEnumKey: - case ftUnionKey: - case ftUnionValue: { - return false; - } - default: { - return true; - } - } - } - - // Determine if a table args rust type needs a lifetime template parameter. - bool TableBuilderArgsNeedsLifetime(const StructDef &struct_def) const { - FLATBUFFERS_ASSERT(!struct_def.fixed); - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { continue; } - - if (TableBuilderTypeNeedsLifetime(field.value.type)) { return true; } - } - - return false; - } - - std::string EscapeKeyword(const std::string &name) const { - return keywords_.find(name) == keywords_.end() ? name : name + "_"; - } - std::string NamespacedNativeName(const Definition &def) { - return WrapInNameSpace(def.defined_namespace, NativeName(def)); - } - - std::string NativeName(const Definition &def) { - return parser_.opts.object_prefix + Name(def) + parser_.opts.object_suffix; - } - - std::string Name(const Definition &def) const { - return EscapeKeyword(def.name); - } - - std::string Name(const EnumVal &ev) const { return EscapeKeyword(ev.name); } - - std::string WrapInNameSpace(const Definition &def) const { - return WrapInNameSpace(def.defined_namespace, Name(def)); - } - std::string WrapInNameSpace(const Namespace *ns, - const std::string &name) const { - if (CurrentNameSpace() == ns) return name; - std::string prefix = GetRelativeNamespaceTraversal(CurrentNameSpace(), ns); - return prefix + name; - } - - // Determine the namespace traversal needed from the Rust crate root. - // This may be useful in the future for referring to included files, but is - // currently unused. - std::string GetAbsoluteNamespaceTraversal(const Namespace *dst) const { - std::stringstream stream; - - stream << "::"; - for (auto d = dst->components.begin(); d != dst->components.end(); ++d) { - stream << MakeSnakeCase(*d) + "::"; - } - return stream.str(); - } - - // Determine the relative namespace traversal needed to reference one - // namespace from another namespace. This is useful because it does not force - // the user to have a particular file layout. (If we output absolute - // namespace paths, that may require users to organize their Rust crates in a - // particular way.) - std::string GetRelativeNamespaceTraversal(const Namespace *src, - const Namespace *dst) const { - // calculate the path needed to reference dst from src. - // example: f(A::B::C, A::B::C) -> (none) - // example: f(A::B::C, A::B) -> super:: - // example: f(A::B::C, A::B::D) -> super::D - // example: f(A::B::C, A) -> super::super:: - // example: f(A::B::C, D) -> super::super::super::D - // example: f(A::B::C, D::E) -> super::super::super::D::E - // example: f(A, D::E) -> super::D::E - // does not include leaf object (typically a struct type). - - size_t i = 0; - std::stringstream stream; - - auto s = src->components.begin(); - auto d = dst->components.begin(); - for (;;) { - if (s == src->components.end()) { break; } - if (d == dst->components.end()) { break; } - if (*s != *d) { break; } - ++s; - ++d; - ++i; - } - - for (; s != src->components.end(); ++s) { stream << "super::"; } - for (; d != dst->components.end(); ++d) { - stream << MakeSnakeCase(*d) + "::"; - } - return stream.str(); - } - - // Generate a comment from the schema. - void GenComment(const std::vector<std::string> &dc, const char *prefix = "") { - std::string text; - ::flatbuffers::GenComment(dc, &text, nullptr, prefix); - code_ += text + "\\"; - } - - // Return a Rust type from the table in idl.h. - std::string GetTypeBasic(const Type &type) const { - switch (GetFullType(type)) { - case ftInteger: - case ftFloat: - case ftBool: - case ftEnumKey: - case ftUnionKey: { - break; - } - default: { - FLATBUFFERS_ASSERT(false && "incorrect type given"); - } - } - - // clang-format off - static const char * const ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, ...) \ - #RTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - - if (type.enum_def) { return WrapInNameSpace(*type.enum_def); } - return ctypename[type.base_type]; - } - - // Look up the native type for an enum. This will always be an integer like - // u8, i32, etc. - std::string GetEnumTypeForDecl(const Type &type) { - const auto ft = GetFullType(type); - if (!(ft == ftEnumKey || ft == ftUnionKey)) { - FLATBUFFERS_ASSERT(false && "precondition failed in GetEnumTypeForDecl"); - } - - // clang-format off - static const char *ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, ...) \ - #RTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - - // Enums can be bools, but their Rust representation must be a u8, as used - // in the repr attribute (#[repr(bool)] is an invalid attribute). - if (type.base_type == BASE_TYPE_BOOL) return "u8"; - return ctypename[type.base_type]; - } - - // Return a Rust type for any type (scalar, table, struct) specifically for - // using a FlatBuffer. - std::string GetTypeGet(const Type &type) const { - switch (GetFullType(type)) { - case ftInteger: - case ftFloat: - case ftBool: - case ftEnumKey: - case ftUnionKey: { - return GetTypeBasic(type); - } - case ftArrayOfBuiltin: - case ftArrayOfEnum: - case ftArrayOfStruct: { - return "[" + GetTypeGet(type.VectorType()) + "; " + - NumToString(type.fixed_length) + "]"; - } - case ftTable: { - return WrapInNameSpace(type.struct_def->defined_namespace, - type.struct_def->name) + - "<'a>"; - } - default: { - return WrapInNameSpace(type.struct_def->defined_namespace, - type.struct_def->name); - } - } - } - - std::string GetEnumValue(const EnumDef &enum_def, - const EnumVal &enum_val) const { - return Name(enum_def) + "::" + Name(enum_val); - } - - // 1 suffix since old C++ can't figure out the overload. - void ForAllEnumValues1(const EnumDef &enum_def, - std::function<void(const EnumVal &)> cb) { - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - const auto &ev = **it; - code_.SetValue("VARIANT", Name(ev)); - code_.SetValue("VALUE", enum_def.ToString(ev)); - cb(ev); - } - } - void ForAllEnumValues(const EnumDef &enum_def, std::function<void()> cb) { - std::function<void(const EnumVal &)> wrapped = [&](const EnumVal &unused) { - (void)unused; - cb(); - }; - ForAllEnumValues1(enum_def, wrapped); - } - // Generate an enum declaration, - // an enum string lookup table, - // an enum match function, - // and an enum array of values - void GenEnum(const EnumDef &enum_def) { - code_.SetValue("ENUM_NAME", Name(enum_def)); - code_.SetValue("BASE_TYPE", GetEnumTypeForDecl(enum_def.underlying_type)); - code_.SetValue("ENUM_NAME_SNAKE", MakeSnakeCase(Name(enum_def))); - code_.SetValue("ENUM_NAME_CAPS", MakeUpper(MakeSnakeCase(Name(enum_def)))); - const EnumVal *minv = enum_def.MinValue(); - const EnumVal *maxv = enum_def.MaxValue(); - FLATBUFFERS_ASSERT(minv && maxv); - code_.SetValue("ENUM_MIN_BASE_VALUE", enum_def.ToString(*minv)); - code_.SetValue("ENUM_MAX_BASE_VALUE", enum_def.ToString(*maxv)); - - if (IsBitFlagsEnum(enum_def)) { - // Defer to the convenient and canonical bitflags crate. We declare it in - // a module to #allow camel case constants in a smaller scope. This - // matches Flatbuffers c-modeled enums where variants are associated - // constants but in camel case. - code_ += "#[allow(non_upper_case_globals)]"; - code_ += "mod bitflags_{{ENUM_NAME_SNAKE}} {"; - code_ += " flatbuffers::bitflags::bitflags! {"; - GenComment(enum_def.doc_comment, " "); - code_ += " #[derive(Default)]"; - code_ += " pub struct {{ENUM_NAME}}: {{BASE_TYPE}} {"; - ForAllEnumValues1(enum_def, [&](const EnumVal &ev) { - this->GenComment(ev.doc_comment, " "); - code_ += " const {{VARIANT}} = {{VALUE}};"; - }); - code_ += " }"; - code_ += " }"; - code_ += "}"; - code_ += "pub use self::bitflags_{{ENUM_NAME_SNAKE}}::{{ENUM_NAME}};"; - code_ += ""; - - code_.SetValue("FROM_BASE", "unsafe { Self::from_bits_unchecked(b) }"); - code_.SetValue("INTO_BASE", "self.bits()"); - } else { - // Normal, c-modelled enums. - // Deprecated associated constants; - const std::string deprecation_warning = - "#[deprecated(since = \"2.0.0\", note = \"Use associated constants" - " instead. This will no longer be generated in 2021.\")]"; - code_ += deprecation_warning; - code_ += - "pub const ENUM_MIN_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}}" - " = {{ENUM_MIN_BASE_VALUE}};"; - code_ += deprecation_warning; - code_ += - "pub const ENUM_MAX_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}}" - " = {{ENUM_MAX_BASE_VALUE}};"; - auto num_fields = NumToString(enum_def.size()); - code_ += deprecation_warning; - code_ += "#[allow(non_camel_case_types)]"; - code_ += "pub const ENUM_VALUES_{{ENUM_NAME_CAPS}}: [{{ENUM_NAME}}; " + - num_fields + "] = ["; - ForAllEnumValues1(enum_def, [&](const EnumVal &ev) { - code_ += " " + GetEnumValue(enum_def, ev) + ","; - }); - code_ += "];"; - code_ += ""; - - GenComment(enum_def.doc_comment); - // Derive Default to be 0. flatc enforces this when the enum - // is put into a struct, though this isn't documented behavior, it is - // needed to derive defaults in struct objects. - code_ += - "#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, " - "Default)]"; - code_ += "#[repr(transparent)]"; - code_ += "pub struct {{ENUM_NAME}}(pub {{BASE_TYPE}});"; - code_ += "#[allow(non_upper_case_globals)]"; - code_ += "impl {{ENUM_NAME}} {"; - ForAllEnumValues1(enum_def, [&](const EnumVal &ev) { - this->GenComment(ev.doc_comment, " "); - code_ += " pub const {{VARIANT}}: Self = Self({{VALUE}});"; - }); - code_ += ""; - // Generate Associated constants - code_ += " pub const ENUM_MIN: {{BASE_TYPE}} = {{ENUM_MIN_BASE_VALUE}};"; - code_ += " pub const ENUM_MAX: {{BASE_TYPE}} = {{ENUM_MAX_BASE_VALUE}};"; - code_ += " pub const ENUM_VALUES: &'static [Self] = &["; - ForAllEnumValues(enum_def, [&]() { code_ += " Self::{{VARIANT}},"; }); - code_ += " ];"; - code_ += " /// Returns the variant's name or \"\" if unknown."; - code_ += " pub fn variant_name(self) -> Option<&'static str> {"; - code_ += " match self {"; - ForAllEnumValues(enum_def, [&]() { - code_ += " Self::{{VARIANT}} => Some(\"{{VARIANT}}\"),"; - }); - code_ += " _ => None,"; - code_ += " }"; - code_ += " }"; - code_ += "}"; - - // Generate Debug. Unknown variants are printed like "<UNKNOWN 42>". - code_ += "impl std::fmt::Debug for {{ENUM_NAME}} {"; - code_ += - " fn fmt(&self, f: &mut std::fmt::Formatter) ->" - " std::fmt::Result {"; - code_ += " if let Some(name) = self.variant_name() {"; - code_ += " f.write_str(name)"; - code_ += " } else {"; - code_ += " f.write_fmt(format_args!(\"<UNKNOWN {:?}>\", self.0))"; - code_ += " }"; - code_ += " }"; - code_ += "}"; - - code_.SetValue("FROM_BASE", "Self(b)"); - code_.SetValue("INTO_BASE", "self.0"); - } - - // Generate Follow and Push so we can serialize and stuff. - code_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_NAME}} {"; - code_ += " type Inner = Self;"; - code_ += " #[inline]"; - code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; - code_ += " let b = unsafe {"; - code_ += " flatbuffers::read_scalar_at::<{{BASE_TYPE}}>(buf, loc)"; - code_ += " };"; - code_ += " {{FROM_BASE}}"; - code_ += " }"; - code_ += "}"; - code_ += ""; - code_ += "impl flatbuffers::Push for {{ENUM_NAME}} {"; - code_ += " type Output = {{ENUM_NAME}};"; - code_ += " #[inline]"; - code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {"; - code_ += - " unsafe { flatbuffers::emplace_scalar::<{{BASE_TYPE}}>" - "(dst, {{INTO_BASE}}); }"; - code_ += " }"; - code_ += "}"; - code_ += ""; - code_ += "impl flatbuffers::EndianScalar for {{ENUM_NAME}} {"; - code_ += " #[inline]"; - code_ += " fn to_little_endian(self) -> Self {"; - code_ += " let b = {{BASE_TYPE}}::to_le({{INTO_BASE}});"; - code_ += " {{FROM_BASE}}"; - code_ += " }"; - code_ += " #[inline]"; - code_ += " #[allow(clippy::wrong_self_convention)]"; - code_ += " fn from_little_endian(self) -> Self {"; - code_ += " let b = {{BASE_TYPE}}::from_le({{INTO_BASE}});"; - code_ += " {{FROM_BASE}}"; - code_ += " }"; - code_ += "}"; - code_ += ""; - - // Generate verifier - deferring to the base type. - code_ += "impl<'a> flatbuffers::Verifiable for {{ENUM_NAME}} {"; - code_ += " #[inline]"; - code_ += " fn run_verifier("; - code_ += " v: &mut flatbuffers::Verifier, pos: usize"; - code_ += " ) -> Result<(), flatbuffers::InvalidFlatbuffer> {"; - code_ += " use self::flatbuffers::Verifiable;"; - code_ += " {{BASE_TYPE}}::run_verifier(v, pos)"; - code_ += " }"; - code_ += "}"; - code_ += ""; - // Enums are basically integers. - code_ += "impl flatbuffers::SimpleToVerifyInSlice for {{ENUM_NAME}} {}"; - - if (enum_def.is_union) { - // Generate typesafe offset(s) for unions - code_.SetValue("NAME", Name(enum_def)); - code_.SetValue("UNION_OFFSET_NAME", Name(enum_def) + "UnionTableOffset"); - code_ += "pub struct {{UNION_OFFSET_NAME}} {}"; - code_ += ""; - if (parser_.opts.generate_object_based_api) { GenUnionObject(enum_def); } - } - } - - // CASPER: dedup Object versions from non object versions. - void ForAllUnionObjectVariantsBesidesNone(const EnumDef &enum_def, - std::function<void()> cb) { - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &enum_val = **it; - if (enum_val.union_type.base_type == BASE_TYPE_NONE) continue; - code_.SetValue("VARIANT_NAME", Name(enum_val)); - code_.SetValue("NATIVE_VARIANT", MakeCamel(Name(enum_val))); - code_.SetValue("U_ELEMENT_NAME", MakeSnakeCase(Name(enum_val))); - code_.SetValue("U_ELEMENT_TABLE_TYPE", - NamespacedNativeName(*enum_val.union_type.struct_def)); - cb(); - } - } - void GenUnionObject(const EnumDef &enum_def) { - code_.SetValue("ENUM_NAME", Name(enum_def)); - code_.SetValue("ENUM_NAME_SNAKE", MakeSnakeCase(Name(enum_def))); - code_.SetValue("NATIVE_NAME", NativeName(enum_def)); - - // Generate native union. - code_ += "#[non_exhaustive]"; - code_ += "#[derive(Debug, Clone, PartialEq)]"; - code_ += "pub enum {{NATIVE_NAME}} {"; - code_ += " NONE,"; - ForAllUnionObjectVariantsBesidesNone(enum_def, [&] { - code_ += " {{NATIVE_VARIANT}}(Box<{{U_ELEMENT_TABLE_TYPE}}>),"; - }); - code_ += "}"; - // Generate Default (NONE). - code_ += "impl Default for {{NATIVE_NAME}} {"; - code_ += " fn default() -> Self {"; - code_ += " Self::NONE"; - code_ += " }"; - code_ += "}"; - - // Generate native union methods. - code_ += "impl {{NATIVE_NAME}} {"; - - // Get flatbuffers union key. - // CASPER: add docstrings? - code_ += " pub fn {{ENUM_NAME_SNAKE}}_type(&self) -> {{ENUM_NAME}} {"; - code_ += " match self {"; - code_ += " Self::NONE => {{ENUM_NAME}}::NONE,"; - ForAllUnionObjectVariantsBesidesNone(enum_def, [&] { - code_ += - " Self::{{NATIVE_VARIANT}}(_) => {{ENUM_NAME}}::" - "{{VARIANT_NAME}},"; - }); - code_ += " }"; - code_ += " }"; - // Pack flatbuffers union value - code_ += - " pub fn pack(&self, fbb: &mut flatbuffers::FlatBufferBuilder)" - " -> Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>" - " {"; - code_ += " match self {"; - code_ += " Self::NONE => None,"; - ForAllUnionObjectVariantsBesidesNone(enum_def, [&] { - code_ += - " Self::{{NATIVE_VARIANT}}(v) => " - "Some(v.pack(fbb).as_union_value()),"; - }); - code_ += " }"; - code_ += " }"; - - // Generate some accessors; - ForAllUnionObjectVariantsBesidesNone(enum_def, [&] { - // Move accessor. - code_ += - " /// If the union variant matches, return the owned " - "{{U_ELEMENT_TABLE_TYPE}}, setting the union to NONE."; - code_ += - " pub fn take_{{U_ELEMENT_NAME}}(&mut self) -> " - "Option<Box<{{U_ELEMENT_TABLE_TYPE}}>> {"; - code_ += " if let Self::{{NATIVE_VARIANT}}(_) = self {"; - code_ += " let v = std::mem::replace(self, Self::NONE);"; - code_ += " if let Self::{{NATIVE_VARIANT}}(w) = v {"; - code_ += " Some(w)"; - code_ += " } else {"; - code_ += " unreachable!()"; - code_ += " }"; - code_ += " } else {"; - code_ += " None"; - code_ += " }"; - code_ += " }"; - // Immutable reference accessor. - code_ += - " /// If the union variant matches, return a reference to the " - "{{U_ELEMENT_TABLE_TYPE}}."; - code_ += - " pub fn as_{{U_ELEMENT_NAME}}(&self) -> " - "Option<&{{U_ELEMENT_TABLE_TYPE}}> {"; - code_ += - " if let Self::{{NATIVE_VARIANT}}(v) = self " - "{ Some(v.as_ref()) } else { None }"; - code_ += " }"; - // Mutable reference accessor. - code_ += - " /// If the union variant matches, return a mutable reference" - " to the {{U_ELEMENT_TABLE_TYPE}}."; - code_ += - " pub fn as_{{U_ELEMENT_NAME}}_mut(&mut self) -> " - "Option<&mut {{U_ELEMENT_TABLE_TYPE}}> {"; - code_ += - " if let Self::{{NATIVE_VARIANT}}(v) = self " - "{ Some(v.as_mut()) } else { None }"; - code_ += " }"; - }); - code_ += "}"; // End union methods impl. - } - - std::string GetFieldOffsetName(const FieldDef &field) { - return "VT_" + MakeUpper(Name(field)); - } - - enum DefaultContext { kBuilder, kAccessor, kObject }; - std::string GetDefaultValue(const FieldDef &field, - const DefaultContext context) { - if (context == kBuilder) { - // Builders and Args structs model nonscalars "optional" even if they're - // required or have defaults according to the schema. I guess its because - // WIPOffset is not nullable. - if (!IsScalar(field.value.type.base_type) || field.IsOptional()) { - return "None"; - } - } else { - // This for defaults in objects. - // Unions have a NONE variant instead of using Rust's None. - if (field.IsOptional() && !IsUnion(field.value.type)) { return "None"; } - } - switch (GetFullType(field.value.type)) { - case ftInteger: - case ftFloat: { - return field.value.constant; - } - case ftBool: { - return field.value.constant == "0" ? "false" : "true"; - } - case ftUnionKey: - case ftEnumKey: { - auto ev = field.value.type.enum_def->FindByValue(field.value.constant); - if (!ev) return "Default::default()"; // Bitflags enum. - return WrapInNameSpace(field.value.type.enum_def->defined_namespace, - GetEnumValue(*field.value.type.enum_def, *ev)); - } - case ftUnionValue: { - return ObjectFieldType(field, true) + "::NONE"; - } - case ftString: { - // Required fields do not have defaults defined by the schema, but we - // need one for Rust's Default trait so we use empty string. The usual - // value of field.value.constant is `0`, which is non-sensical except - // maybe to c++ (nullptr == 0). - // TODO: Escape strings? - const std::string defval = - field.IsRequired() ? "\"\"" : "\"" + field.value.constant + "\""; - if (context == kObject) return defval + ".to_string()"; - if (context == kAccessor) return "&" + defval; - FLATBUFFERS_ASSERT("Unreachable."); - return "INVALID_CODE_GENERATION"; - } - - case ftArrayOfStruct: - case ftArrayOfEnum: - case ftArrayOfBuiltin: - case ftVectorOfBool: - case ftVectorOfFloat: - case ftVectorOfInteger: - case ftVectorOfString: - case ftVectorOfStruct: - case ftVectorOfTable: - case ftVectorOfEnumKey: - case ftVectorOfUnionValue: - case ftStruct: - case ftTable: { - // We only support empty vectors which matches the defaults for - // &[T] and Vec<T> anyway. - // - // For required structs and tables fields, we defer to their object API - // defaults. This works so long as there's nothing recursive happening, - // but `table Infinity { i: Infinity (required); }` does compile. - return "Default::default()"; - } - } - FLATBUFFERS_ASSERT("Unreachable."); - return "INVALID_CODE_GENERATION"; - } - - // Create the return type for fields in the *BuilderArgs structs that are - // used to create Tables. - // - // Note: we could make all inputs to the BuilderArgs be an Option, as well - // as all outputs. But, the UX of Flatbuffers is that the user doesn't get to - // know if the value is default or not, because there are three ways to - // return a default value: - // 1) return a stored value that happens to be the default, - // 2) return a hardcoded value because the relevant vtable field is not in - // the vtable, or - // 3) return a hardcoded value because the vtable field value is set to zero. - std::string TableBuilderArgsDefnType(const FieldDef &field, - const std::string &lifetime) { - const Type &type = field.value.type; - auto WrapOption = [&](std::string s) { - return IsOptionalToBuilder(field) ? "Option<" + s + ">" : s; - }; - auto WrapVector = [&](std::string ty) { - return WrapOption("flatbuffers::WIPOffset<flatbuffers::Vector<" + - lifetime + ", " + ty + ">>"); - }; - auto WrapUOffsetsVector = [&](std::string ty) { - return WrapVector("flatbuffers::ForwardsUOffset<" + ty + ">"); - }; - - switch (GetFullType(type)) { - case ftInteger: - case ftFloat: - case ftBool: { - return WrapOption(GetTypeBasic(type)); - } - case ftStruct: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapOption("&" + lifetime + " " + typname); - } - case ftTable: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapOption("flatbuffers::WIPOffset<" + typname + "<" + lifetime + - ">>"); - } - case ftString: { - return WrapOption("flatbuffers::WIPOffset<&" + lifetime + " str>"); - } - case ftEnumKey: - case ftUnionKey: { - return WrapOption(WrapInNameSpace(*type.enum_def)); - } - case ftUnionValue: { - return "Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>"; - } - - case ftVectorOfInteger: - case ftVectorOfBool: - case ftVectorOfFloat: { - const auto typname = GetTypeBasic(type.VectorType()); - return WrapVector(typname); - } - case ftVectorOfEnumKey: { - const auto typname = WrapInNameSpace(*type.enum_def); - return WrapVector(typname); - } - case ftVectorOfStruct: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapVector(typname); - } - case ftVectorOfTable: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapUOffsetsVector(typname + "<" + lifetime + ">"); - } - case ftVectorOfString: { - return WrapUOffsetsVector("&" + lifetime + " str"); - } - case ftVectorOfUnionValue: { - return WrapUOffsetsVector("flatbuffers::Table<" + lifetime + ">"); - } - case ftArrayOfEnum: - case ftArrayOfStruct: - case ftArrayOfBuiltin: { - FLATBUFFERS_ASSERT(false && "arrays are not supported within tables"); - return "ARRAYS_NOT_SUPPORTED_IN_TABLES"; - } - } - return "INVALID_CODE_GENERATION"; // for return analysis - } - - std::string ObjectFieldType(const FieldDef &field, bool in_a_table) { - const Type &type = field.value.type; - std::string ty; - switch (GetFullType(type)) { - case ftInteger: - case ftBool: - case ftFloat: { - ty = GetTypeBasic(type); - break; - } - case ftString: { - ty = "String"; - break; - } - case ftStruct: { - ty = NamespacedNativeName(*type.struct_def); - break; - } - case ftTable: { - // Since Tables can contain themselves, Box is required to avoid - // infinite types. - ty = "Box<" + NamespacedNativeName(*type.struct_def) + ">"; - break; - } - case ftUnionKey: { - // There is no native "UnionKey", natively, unions are rust enums with - // newtype-struct-variants. - return "INVALID_CODE_GENERATION"; - } - case ftUnionValue: { - ty = NamespacedNativeName(*type.enum_def); - break; - } - case ftEnumKey: { - ty = WrapInNameSpace(*type.enum_def); - break; - } - // Vectors are in tables and are optional - case ftVectorOfEnumKey: { - ty = "Vec<" + WrapInNameSpace(*type.VectorType().enum_def) + ">"; - break; - } - case ftVectorOfInteger: - case ftVectorOfBool: - case ftVectorOfFloat: { - ty = "Vec<" + GetTypeBasic(type.VectorType()) + ">"; - break; - } - case ftVectorOfString: { - ty = "Vec<String>"; - break; - } - case ftVectorOfTable: - case ftVectorOfStruct: { - ty = NamespacedNativeName(*type.VectorType().struct_def); - ty = "Vec<" + ty + ">"; - break; - } - case ftVectorOfUnionValue: { - FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported"); - return "INVALID_CODE_GENERATION"; // OH NO! - } - case ftArrayOfEnum: { - ty = "[" + WrapInNameSpace(*type.VectorType().enum_def) + "; " + - NumToString(type.fixed_length) + "]"; - break; - } - case ftArrayOfStruct: { - ty = "[" + NamespacedNativeName(*type.VectorType().struct_def) + "; " + - NumToString(type.fixed_length) + "]"; - break; - } - case ftArrayOfBuiltin: { - ty = "[" + GetTypeBasic(type.VectorType()) + "; " + - NumToString(type.fixed_length) + "]"; - break; - } - } - if (in_a_table && !IsUnion(type) && field.IsOptional()) { - return "Option<" + ty + ">"; - } else { - return ty; - } - } - - std::string TableBuilderArgsAddFuncType(const FieldDef &field, - const std::string &lifetime) { - const Type &type = field.value.type; - - switch (GetFullType(field.value.type)) { - case ftVectorOfStruct: { - const auto typname = WrapInNameSpace(*type.struct_def); - return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " + - typname + ">>"; - } - case ftVectorOfTable: { - const auto typname = WrapInNameSpace(*type.struct_def); - return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + - ", flatbuffers::ForwardsUOffset<" + typname + "<" + lifetime + - ">>>>"; - } - case ftVectorOfInteger: - case ftVectorOfBool: - case ftVectorOfFloat: { - const auto typname = GetTypeBasic(type.VectorType()); - return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " + - typname + ">>"; - } - case ftVectorOfString: { - return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + - ", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>>"; - } - case ftVectorOfEnumKey: { - const auto typname = WrapInNameSpace(*type.enum_def); - return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " + - typname + ">>"; - } - case ftVectorOfUnionValue: { - return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + - ", flatbuffers::ForwardsUOffset<flatbuffers::Table<" + lifetime + - ">>>"; - } - case ftEnumKey: - case ftUnionKey: { - const auto typname = WrapInNameSpace(*type.enum_def); - return typname; - } - case ftStruct: { - const auto typname = WrapInNameSpace(*type.struct_def); - return "&" + typname + ""; - } - case ftTable: { - const auto typname = WrapInNameSpace(*type.struct_def); - return "flatbuffers::WIPOffset<" + typname + "<" + lifetime + ">>"; - } - case ftInteger: - case ftBool: - case ftFloat: { - return GetTypeBasic(type); - } - case ftString: { - return "flatbuffers::WIPOffset<&" + lifetime + " str>"; - } - case ftUnionValue: { - return "flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>"; - } - case ftArrayOfBuiltin: { - const auto typname = GetTypeBasic(type.VectorType()); - return "flatbuffers::Array<" + lifetime + ", " + typname + ", " + - NumToString(type.fixed_length) + ">"; - } - case ftArrayOfEnum: { - const auto typname = WrapInNameSpace(*type.enum_def); - return "flatbuffers::Array<" + lifetime + ", " + typname + ", " + - NumToString(type.fixed_length) + ">"; - } - case ftArrayOfStruct: { - const auto typname = WrapInNameSpace(*type.struct_def); - return "flatbuffers::Array<" + lifetime + ", " + typname + ", " + - NumToString(type.fixed_length) + ">"; - } - } - - return "INVALID_CODE_GENERATION"; // for return analysis - } - - std::string TableBuilderArgsAddFuncBody(const FieldDef &field) { - const Type &type = field.value.type; - - switch (GetFullType(field.value.type)) { - case ftInteger: - case ftBool: - case ftFloat: { - const auto typname = GetTypeBasic(field.value.type); - return (field.IsOptional() ? "self.fbb_.push_slot_always::<" - : "self.fbb_.push_slot::<") + - typname + ">"; - } - case ftEnumKey: - case ftUnionKey: { - const auto underlying_typname = GetTypeBasic(type); - return (field.IsOptional() ? "self.fbb_.push_slot_always::<" - : "self.fbb_.push_slot::<") + - underlying_typname + ">"; - } - - case ftStruct: { - const std::string typname = WrapInNameSpace(*type.struct_def); - return "self.fbb_.push_slot_always::<&" + typname + ">"; - } - case ftTable: { - const auto typname = WrapInNameSpace(*type.struct_def); - return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<" + - typname + ">>"; - } - - case ftUnionValue: - case ftString: - case ftVectorOfInteger: - case ftVectorOfFloat: - case ftVectorOfBool: - case ftVectorOfEnumKey: - case ftVectorOfStruct: - case ftVectorOfTable: - case ftVectorOfString: - case ftVectorOfUnionValue: { - return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>"; - } - case ftArrayOfEnum: - case ftArrayOfStruct: - case ftArrayOfBuiltin: { - FLATBUFFERS_ASSERT(false && "arrays are not supported within tables"); - return "ARRAYS_NOT_SUPPORTED_IN_TABLES"; - } - } - return "INVALID_CODE_GENERATION"; // for return analysis - } - - std::string GenTableAccessorFuncReturnType(const FieldDef &field, - const std::string &lifetime) { - const Type &type = field.value.type; - const auto WrapOption = [&](std::string s) { - return field.IsOptional() ? "Option<" + s + ">" : s; - }; - - switch (GetFullType(field.value.type)) { - case ftInteger: - case ftFloat: - case ftBool: { - return WrapOption(GetTypeBasic(type)); - } - case ftStruct: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapOption("&" + lifetime + " " + typname); - } - case ftTable: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapOption(typname + "<" + lifetime + ">"); - } - case ftEnumKey: - case ftUnionKey: { - return WrapOption(WrapInNameSpace(*type.enum_def)); - } - - case ftUnionValue: { - return WrapOption("flatbuffers::Table<" + lifetime + ">"); - } - case ftString: { - return WrapOption("&" + lifetime + " str"); - } - case ftVectorOfInteger: - case ftVectorOfBool: - case ftVectorOfFloat: { - const auto typname = GetTypeBasic(type.VectorType()); - const auto vector_type = - IsOneByte(type.VectorType().base_type) - ? "&" + lifetime + " [" + typname + "]" - : "flatbuffers::Vector<" + lifetime + ", " + typname + ">"; - return WrapOption(vector_type); - } - case ftVectorOfEnumKey: { - const auto typname = WrapInNameSpace(*type.enum_def); - return WrapOption("flatbuffers::Vector<" + lifetime + ", " + typname + - ">"); - } - case ftVectorOfStruct: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapOption("&" + lifetime + " [" + typname + "]"); - } - case ftVectorOfTable: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapOption("flatbuffers::Vector<" + lifetime + - ", flatbuffers::ForwardsUOffset<" + typname + "<" + - lifetime + ">>>"); - } - case ftVectorOfString: { - return WrapOption("flatbuffers::Vector<" + lifetime + - ", flatbuffers::ForwardsUOffset<&" + lifetime + - " str>>"); - } - case ftVectorOfUnionValue: { - FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported"); - // TODO(rw): when we do support these, we should consider using the - // Into trait to convert tables to typesafe union values. - return "INVALID_CODE_GENERATION"; // for return analysis - } - case ftArrayOfEnum: - case ftArrayOfStruct: - case ftArrayOfBuiltin: { - FLATBUFFERS_ASSERT(false && "arrays are not supported within tables"); - return "ARRAYS_NOT_SUPPORTED_IN_TABLES"; - } - } - return "INVALID_CODE_GENERATION"; // for return analysis - } - - std::string FollowType(const Type &type, const std::string &lifetime) { - // IsVector... This can be made iterative? - - const auto WrapForwardsUOffset = [](std::string ty) -> std::string { - return "flatbuffers::ForwardsUOffset<" + ty + ">"; - }; - const auto WrapVector = [&](std::string ty) -> std::string { - return "flatbuffers::Vector<" + lifetime + ", " + ty + ">"; - }; - const auto WrapArray = [&](std::string ty, uint16_t length) -> std::string { - return "flatbuffers::Array<" + lifetime + ", " + ty + ", " + - NumToString(length) + ">"; - }; - switch (GetFullType(type)) { - case ftInteger: - case ftFloat: - case ftBool: { - return GetTypeBasic(type); - } - case ftStruct: { - return WrapInNameSpace(*type.struct_def); - } - case ftUnionKey: - case ftEnumKey: { - return WrapInNameSpace(*type.enum_def); - } - case ftTable: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapForwardsUOffset(typname); - } - case ftUnionValue: { - return WrapForwardsUOffset("flatbuffers::Table<" + lifetime + ">"); - } - case ftString: { - return WrapForwardsUOffset("&str"); - } - case ftVectorOfInteger: - case ftVectorOfBool: - case ftVectorOfFloat: { - const auto typname = GetTypeBasic(type.VectorType()); - return WrapForwardsUOffset(WrapVector(typname)); - } - case ftVectorOfEnumKey: { - const auto typname = WrapInNameSpace(*type.VectorType().enum_def); - return WrapForwardsUOffset(WrapVector(typname)); - } - case ftVectorOfStruct: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapForwardsUOffset(WrapVector(typname)); - } - case ftVectorOfTable: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapForwardsUOffset(WrapVector(WrapForwardsUOffset(typname))); - } - case ftVectorOfString: { - return WrapForwardsUOffset( - WrapVector(WrapForwardsUOffset("&" + lifetime + " str"))); - } - case ftVectorOfUnionValue: { - FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported"); - return "INVALID_CODE_GENERATION"; // for return analysis - } - case ftArrayOfEnum: { - const auto typname = WrapInNameSpace(*type.VectorType().enum_def); - return WrapArray(typname, type.fixed_length); - } - case ftArrayOfStruct: { - const auto typname = WrapInNameSpace(*type.struct_def); - return WrapArray(typname, type.fixed_length); - } - case ftArrayOfBuiltin: { - const auto typname = GetTypeBasic(type.VectorType()); - return WrapArray(typname, type.fixed_length); - } - } - return "INVALID_CODE_GENERATION"; // for return analysis - } - - std::string GenTableAccessorFuncBody(const FieldDef &field, - const std::string &lifetime) { - const std::string vt_offset = GetFieldOffsetName(field); - const std::string typname = FollowType(field.value.type, lifetime); - // Default-y fields (scalars so far) are neither optional nor required. - const std::string default_value = - !(field.IsOptional() || field.IsRequired()) - ? "Some(" + GetDefaultValue(field, kAccessor) + ")" - : "None"; - const std::string unwrap = field.IsOptional() ? "" : ".unwrap()"; - - const auto t = GetFullType(field.value.type); - - // TODO(caspern): Shouldn't 1byte VectorOfEnumKey be slice too? - const std::string safe_slice = - (t == ftVectorOfStruct || - ((t == ftVectorOfBool || t == ftVectorOfFloat || - t == ftVectorOfInteger) && - IsOneByte(field.value.type.VectorType().base_type))) - ? ".map(|v| v.safe_slice())" - : ""; - - return "self._tab.get::<" + typname + ">({{STRUCT_NAME}}::" + vt_offset + - ", " + default_value + ")" + safe_slice + unwrap; - } - - // Generates a fully-qualified name getter for use with --gen-name-strings - void GenFullyQualifiedNameGetter(const StructDef &struct_def, - const std::string &name) { - code_ += " pub const fn get_fully_qualified_name() -> &'static str {"; - code_ += " \"" + - struct_def.defined_namespace->GetFullyQualifiedName(name) + "\""; - code_ += " }"; - code_ += ""; - } - - void ForAllUnionVariantsBesidesNone( - const EnumDef &def, std::function<void(const EnumVal &ev)> cb) { - FLATBUFFERS_ASSERT(def.is_union); - - for (auto it = def.Vals().begin(); it != def.Vals().end(); ++it) { - const EnumVal &ev = **it; - // TODO(cneo): Can variants be deprecated, should we skip them? - if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } - code_.SetValue( - "U_ELEMENT_ENUM_TYPE", - WrapInNameSpace(def.defined_namespace, GetEnumValue(def, ev))); - code_.SetValue( - "U_ELEMENT_TABLE_TYPE", - WrapInNameSpace(ev.union_type.struct_def->defined_namespace, - ev.union_type.struct_def->name)); - code_.SetValue("U_ELEMENT_NAME", MakeSnakeCase(Name(ev))); - cb(ev); - } - } - - void ForAllTableFields(const StructDef &struct_def, - std::function<void(const FieldDef &)> cb, - bool reversed = false) { - // TODO(cneo): Remove `reversed` overload. It's only here to minimize the - // diff when refactoring to the `ForAllX` helper functions. - auto go = [&](const FieldDef &field) { - if (field.deprecated) return; - code_.SetValue("OFFSET_NAME", GetFieldOffsetName(field)); - code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset)); - code_.SetValue("FIELD_NAME", Name(field)); - code_.SetValue("BLDR_DEF_VAL", GetDefaultValue(field, kBuilder)); - cb(field); - }; - const auto &fields = struct_def.fields.vec; - if (reversed) { - for (auto it = fields.rbegin(); it != fields.rend(); ++it) go(**it); - } else { - for (auto it = fields.begin(); it != fields.end(); ++it) go(**it); - } - } - // Generate an accessor struct, builder struct, and create function for a - // table. - void GenTable(const StructDef &struct_def) { - code_.SetValue("STRUCT_NAME", Name(struct_def)); - code_.SetValue("OFFSET_TYPELABEL", Name(struct_def) + "Offset"); - code_.SetValue("STRUCT_NAME_SNAKECASE", MakeSnakeCase(Name(struct_def))); - - // Generate an offset type, the base type, the Follow impl, and the - // init_from_table impl. - code_ += "pub enum {{OFFSET_TYPELABEL}} {}"; - code_ += "#[derive(Copy, Clone, PartialEq)]"; - code_ += ""; - - GenComment(struct_def.doc_comment); - - code_ += "pub struct {{STRUCT_NAME}}<'a> {"; - code_ += " pub _tab: flatbuffers::Table<'a>,"; - code_ += "}"; - code_ += ""; - code_ += "impl<'a> flatbuffers::Follow<'a> for {{STRUCT_NAME}}<'a> {"; - code_ += " type Inner = {{STRUCT_NAME}}<'a>;"; - code_ += " #[inline]"; - code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; - code_ += " Self { _tab: flatbuffers::Table { buf, loc } }"; - code_ += " }"; - code_ += "}"; - code_ += ""; - code_ += "impl<'a> {{STRUCT_NAME}}<'a> {"; - - if (parser_.opts.generate_name_strings) { - GenFullyQualifiedNameGetter(struct_def, struct_def.name); - } - - code_ += " #[inline]"; - code_ += - " pub fn init_from_table(table: flatbuffers::Table<'a>) -> " - "Self {"; - code_ += " {{STRUCT_NAME}} { _tab: table }"; - code_ += " }"; - - // Generate a convenient create* function that uses the above builder - // to create a table in one function call. - code_.SetValue("MAYBE_US", struct_def.fields.vec.size() == 0 ? "_" : ""); - code_.SetValue("MAYBE_LT", - TableBuilderArgsNeedsLifetime(struct_def) ? "<'args>" : ""); - code_ += " #[allow(unused_mut)]"; - code_ += " pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>("; - code_ += - " _fbb: " - "&'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,"; - code_ += - " {{MAYBE_US}}args: &'args {{STRUCT_NAME}}Args{{MAYBE_LT}})" - " -> flatbuffers::WIPOffset<{{STRUCT_NAME}}<'bldr>> {"; - - code_ += " let mut builder = {{STRUCT_NAME}}Builder::new(_fbb);"; - for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1; - size; size /= 2) { - ForAllTableFields( - struct_def, - [&](const FieldDef &field) { - if (struct_def.sortbysize && - size != SizeOf(field.value.type.base_type)) - return; - if (IsOptionalToBuilder(field)) { - code_ += - " if let Some(x) = args.{{FIELD_NAME}} " - "{ builder.add_{{FIELD_NAME}}(x); }"; - } else { - code_ += " builder.add_{{FIELD_NAME}}(args.{{FIELD_NAME}});"; - } - }, - /*reverse=*/true); - } - code_ += " builder.finish()"; - code_ += " }"; - code_ += ""; - // Generate Object API Packer function. - if (parser_.opts.generate_object_based_api) { - // TODO(cneo): Replace more for loops with ForAllX stuff. - // TODO(cneo): Manage indentation with IncrementIdentLevel? - code_.SetValue("OBJECT_NAME", NativeName(struct_def)); - code_ += " pub fn unpack(&self) -> {{OBJECT_NAME}} {"; - ForAllObjectTableFields(struct_def, [&](const FieldDef &field) { - const Type &type = field.value.type; - switch (GetFullType(type)) { - case ftInteger: - case ftBool: - case ftFloat: - case ftEnumKey: { - code_ += " let {{FIELD_NAME}} = self.{{FIELD_NAME}}();"; - return; - } - case ftUnionKey: return; - case ftUnionValue: { - const auto &enum_def = *type.enum_def; - code_.SetValue("ENUM_NAME", WrapInNameSpace(enum_def)); - code_.SetValue("NATIVE_ENUM_NAME", NamespacedNativeName(enum_def)); - code_ += - " let {{FIELD_NAME}} = match " - "self.{{FIELD_NAME}}_type() {"; - code_ += - " {{ENUM_NAME}}::NONE =>" - " {{NATIVE_ENUM_NAME}}::NONE,"; - ForAllUnionObjectVariantsBesidesNone(enum_def, [&] { - code_ += - " {{ENUM_NAME}}::{{VARIANT_NAME}} => " - "{{NATIVE_ENUM_NAME}}::{{NATIVE_VARIANT}}(Box::new("; - code_ += - " self.{{FIELD_NAME}}_as_" - "{{U_ELEMENT_NAME}}()"; - code_ += - " .expect(\"Invalid union table, " - "expected `{{ENUM_NAME}}::{{VARIANT_NAME}}`.\")"; - code_ += " .unpack()"; - code_ += " )),"; - }); - // Maybe we shouldn't throw away unknown discriminants? - code_ += " _ => {{NATIVE_ENUM_NAME}}::NONE,"; - code_ += " };"; - return; - } - // The rest of the types need special handling based on if the field - // is optional or not. - case ftString: { - code_.SetValue("EXPR", "x.to_string()"); - break; - } - case ftStruct: { - code_.SetValue("EXPR", "x.unpack()"); - break; - } - case ftTable: { - code_.SetValue("EXPR", "Box::new(x.unpack())"); - break; - } - case ftVectorOfInteger: - case ftVectorOfBool: { - if (IsOneByte(type.VectorType().base_type)) { - // 1 byte stuff is viewed w/ slice instead of flatbuffer::Vector - // and thus needs to be cloned out of the slice. - code_.SetValue("EXPR", "x.to_vec()"); - break; - } - code_.SetValue("EXPR", "x.into_iter().collect()"); - break; - } - case ftVectorOfFloat: - case ftVectorOfEnumKey: { - code_.SetValue("EXPR", "x.into_iter().collect()"); - break; - } - case ftVectorOfString: { - code_.SetValue("EXPR", "x.iter().map(|s| s.to_string()).collect()"); - break; - } - case ftVectorOfStruct: - case ftVectorOfTable: { - code_.SetValue("EXPR", "x.iter().map(|t| t.unpack()).collect()"); - break; - } - case ftVectorOfUnionValue: { - FLATBUFFERS_ASSERT(false && "vectors of unions not yet supported"); - return; - } - case ftArrayOfEnum: - case ftArrayOfStruct: - case ftArrayOfBuiltin: { - FLATBUFFERS_ASSERT(false && - "arrays are not supported within tables"); - return; - } - } - if (field.IsOptional()) { - code_ += " let {{FIELD_NAME}} = self.{{FIELD_NAME}}().map(|x| {"; - code_ += " {{EXPR}}"; - code_ += " });"; - } else { - code_ += " let {{FIELD_NAME}} = {"; - code_ += " let x = self.{{FIELD_NAME}}();"; - code_ += " {{EXPR}}"; - code_ += " };"; - } - }); - code_ += " {{OBJECT_NAME}} {"; - ForAllObjectTableFields(struct_def, [&](const FieldDef &field) { - if (field.value.type.base_type == BASE_TYPE_UTYPE) return; - code_ += " {{FIELD_NAME}},"; - }); - code_ += " }"; - code_ += " }"; - } - - // Generate field id constants. - ForAllTableFields(struct_def, [&](const FieldDef &unused) { - (void)unused; - code_ += - " pub const {{OFFSET_NAME}}: flatbuffers::VOffsetT = " - "{{OFFSET_VALUE}};"; - }); - if (struct_def.fields.vec.size() > 0) code_ += ""; - - // Generate the accessors. Each has one of two forms: - // - // If a value can be None: - // pub fn name(&'a self) -> Option<user_facing_type> { - // self._tab.get::<internal_type>(offset, defaultval) - // } - // - // If a value is always Some: - // pub fn name(&'a self) -> user_facing_type { - // self._tab.get::<internal_type>(offset, defaultval).unwrap() - // } - ForAllTableFields(struct_def, [&](const FieldDef &field) { - code_.SetValue("RETURN_TYPE", - GenTableAccessorFuncReturnType(field, "'a")); - - this->GenComment(field.doc_comment, " "); - code_ += " #[inline]"; - code_ += " pub fn {{FIELD_NAME}}(&self) -> {{RETURN_TYPE}} {"; - code_ += " " + GenTableAccessorFuncBody(field, "'a"); - code_ += " }"; - - // Generate a comparison function for this field if it is a key. - if (field.key) { GenKeyFieldMethods(field); } - - // Generate a nested flatbuffer field, if applicable. - auto nested = field.attributes.Lookup("nested_flatbuffer"); - if (nested) { - std::string qualified_name = nested->constant; - auto nested_root = parser_.LookupStruct(nested->constant); - if (nested_root == nullptr) { - qualified_name = parser_.current_namespace_->GetFullyQualifiedName( - nested->constant); - nested_root = parser_.LookupStruct(qualified_name); - } - FLATBUFFERS_ASSERT(nested_root); // Guaranteed to exist by parser. - - code_.SetValue("NESTED", WrapInNameSpace(*nested_root)); - code_ += " pub fn {{FIELD_NAME}}_nested_flatbuffer(&'a self) -> \\"; - if (field.IsRequired()) { - code_ += "{{NESTED}}<'a> {"; - code_ += " let data = self.{{FIELD_NAME}}();"; - code_ += " use flatbuffers::Follow;"; - code_ += - " <flatbuffers::ForwardsUOffset<{{NESTED}}<'a>>>" - "::follow(data, 0)"; - } else { - code_ += "Option<{{NESTED}}<'a>> {"; - code_ += " self.{{FIELD_NAME}}().map(|data| {"; - code_ += " use flatbuffers::Follow;"; - code_ += - " <flatbuffers::ForwardsUOffset<{{NESTED}}<'a>>>" - "::follow(data, 0)"; - code_ += " })"; - } - code_ += " }"; - } - }); - - // Explicit specializations for union accessors - ForAllTableFields(struct_def, [&](const FieldDef &field) { - if (field.value.type.base_type != BASE_TYPE_UNION) return; - code_.SetValue("FIELD_TYPE_FIELD_NAME", field.name); - ForAllUnionVariantsBesidesNone( - *field.value.type.enum_def, [&](const EnumVal &unused) { - (void)unused; - code_ += " #[inline]"; - code_ += " #[allow(non_snake_case)]"; - code_ += - " pub fn {{FIELD_NAME}}_as_{{U_ELEMENT_NAME}}(&self) -> " - "Option<{{U_ELEMENT_TABLE_TYPE}}<'a>> {"; - // If the user defined schemas name a field that clashes with a - // language reserved word, flatc will try to escape the field name - // by appending an underscore. This works well for most cases, - // except one. When generating union accessors (and referring to - // them internally within the code generated here), an extra - // underscore will be appended to the name, causing build failures. - // - // This only happens when unions have members that overlap with - // language reserved words. - // - // To avoid this problem the type field name is used unescaped here: - code_ += - " if self.{{FIELD_TYPE_FIELD_NAME}}_type() == " - "{{U_ELEMENT_ENUM_TYPE}} {"; - - // The following logic is not tested in the integration test, - // as of April 10, 2020 - if (field.IsRequired()) { - code_ += " let u = self.{{FIELD_NAME}}();"; - code_ += - " Some({{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))"; - } else { - code_ += - " self.{{FIELD_NAME}}().map(" - "{{U_ELEMENT_TABLE_TYPE}}::init_from_table)"; - } - code_ += " } else {"; - code_ += " None"; - code_ += " }"; - code_ += " }"; - code_ += ""; - }); - }); - code_ += "}"; // End of table impl. - code_ += ""; - - // Generate Verifier; - code_ += "impl flatbuffers::Verifiable for {{STRUCT_NAME}}<'_> {"; - code_ += " #[inline]"; - code_ += " fn run_verifier("; - code_ += " v: &mut flatbuffers::Verifier, pos: usize"; - code_ += " ) -> Result<(), flatbuffers::InvalidFlatbuffer> {"; - code_ += " use self::flatbuffers::Verifiable;"; - code_ += " v.visit_table(pos)?\\"; - // Escape newline and insert it onthe next line so we can end the builder - // with a nice semicolon. - ForAllTableFields(struct_def, [&](const FieldDef &field) { - if (GetFullType(field.value.type) == ftUnionKey) return; - - code_.SetValue("IS_REQ", field.IsRequired() ? "true" : "false"); - if (GetFullType(field.value.type) != ftUnionValue) { - // All types besides unions. - code_.SetValue("TY", FollowType(field.value.type, "'_")); - code_ += - "\n .visit_field::<{{TY}}>(&\"{{FIELD_NAME}}\", " - "Self::{{OFFSET_NAME}}, {{IS_REQ}})?\\"; - return; - } - // Unions. - EnumDef &union_def = *field.value.type.enum_def; - code_.SetValue("UNION_TYPE", WrapInNameSpace(union_def)); - code_ += - "\n .visit_union::<{{UNION_TYPE}}, _>(" - "&\"{{FIELD_NAME}}_type\", Self::{{OFFSET_NAME}}_TYPE, " - "&\"{{FIELD_NAME}}\", Self::{{OFFSET_NAME}}, {{IS_REQ}}, " - "|key, v, pos| {"; - code_ += " match key {"; - ForAllUnionVariantsBesidesNone(union_def, [&](const EnumVal &unused) { - (void)unused; - code_ += - " {{U_ELEMENT_ENUM_TYPE}} => v.verify_union_variant::" - "<flatbuffers::ForwardsUOffset<{{U_ELEMENT_TABLE_TYPE}}>>(" - "\"{{U_ELEMENT_ENUM_TYPE}}\", pos),"; - }); - code_ += " _ => Ok(()),"; - code_ += " }"; - code_ += " })?\\"; - }); - code_ += "\n .finish();"; - code_ += " Ok(())"; - code_ += " }"; - code_ += "}"; - - // Generate an args struct: - code_.SetValue("MAYBE_LT", - TableBuilderArgsNeedsLifetime(struct_def) ? "<'a>" : ""); - code_ += "pub struct {{STRUCT_NAME}}Args{{MAYBE_LT}} {"; - ForAllTableFields(struct_def, [&](const FieldDef &field) { - code_.SetValue("PARAM_TYPE", TableBuilderArgsDefnType(field, "'a")); - code_ += " pub {{FIELD_NAME}}: {{PARAM_TYPE}},"; - }); - code_ += "}"; - - // Generate an impl of Default for the *Args type: - code_ += "impl<'a> Default for {{STRUCT_NAME}}Args{{MAYBE_LT}} {"; - code_ += " #[inline]"; - code_ += " fn default() -> Self {"; - code_ += " {{STRUCT_NAME}}Args {"; - ForAllTableFields(struct_def, [&](const FieldDef &field) { - code_ += " {{FIELD_NAME}}: {{BLDR_DEF_VAL}},\\"; - code_ += field.IsRequired() ? " // required field" : ""; - }); - code_ += " }"; - code_ += " }"; - code_ += "}"; - - // Generate a builder struct: - code_ += "pub struct {{STRUCT_NAME}}Builder<'a: 'b, 'b> {"; - code_ += " fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,"; - code_ += - " start_: flatbuffers::WIPOffset<" - "flatbuffers::TableUnfinishedWIPOffset>,"; - code_ += "}"; - - // Generate builder functions: - code_ += "impl<'a: 'b, 'b> {{STRUCT_NAME}}Builder<'a, 'b> {"; - ForAllTableFields(struct_def, [&](const FieldDef &field) { - const bool is_scalar = IsScalar(field.value.type.base_type); - std::string offset = GetFieldOffsetName(field); - // Generate functions to add data, which take one of two forms. - // - // If a value has a default: - // fn add_x(x_: type) { - // fbb_.push_slot::<type>(offset, x_, Some(default)); - // } - // - // If a value does not have a default: - // fn add_x(x_: type) { - // fbb_.push_slot_always::<type>(offset, x_); - // } - code_.SetValue("FIELD_OFFSET", Name(struct_def) + "::" + offset); - code_.SetValue("FIELD_TYPE", TableBuilderArgsAddFuncType(field, "'b ")); - code_.SetValue("FUNC_BODY", TableBuilderArgsAddFuncBody(field)); - code_ += " #[inline]"; - code_ += - " pub fn add_{{FIELD_NAME}}(&mut self, {{FIELD_NAME}}: " - "{{FIELD_TYPE}}) {"; - if (is_scalar && !field.IsOptional()) { - code_ += - " {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}}, " - "{{BLDR_DEF_VAL}});"; - } else { - code_ += " {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}});"; - } - code_ += " }"; - }); - - // Struct initializer (all fields required); - code_ += " #[inline]"; - code_ += - " pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> " - "{{STRUCT_NAME}}Builder<'a, 'b> {"; - code_.SetValue("NUM_FIELDS", NumToString(struct_def.fields.vec.size())); - code_ += " let start = _fbb.start_table();"; - code_ += " {{STRUCT_NAME}}Builder {"; - code_ += " fbb_: _fbb,"; - code_ += " start_: start,"; - code_ += " }"; - code_ += " }"; - - // finish() function. - code_ += " #[inline]"; - code_ += - " pub fn finish(self) -> " - "flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>> {"; - code_ += " let o = self.fbb_.end_table(self.start_);"; - - ForAllTableFields(struct_def, [&](const FieldDef &field) { - if (!field.IsRequired()) return; - code_ += - " self.fbb_.required(o, {{STRUCT_NAME}}::{{OFFSET_NAME}}," - "\"{{FIELD_NAME}}\");"; - }); - code_ += " flatbuffers::WIPOffset::new(o.value())"; - code_ += " }"; - code_ += "}"; - code_ += ""; - - code_ += "impl std::fmt::Debug for {{STRUCT_NAME}}<'_> {"; - code_ += - " fn fmt(&self, f: &mut std::fmt::Formatter<'_>" - ") -> std::fmt::Result {"; - code_ += " let mut ds = f.debug_struct(\"{{STRUCT_NAME}}\");"; - ForAllTableFields(struct_def, [&](const FieldDef &field) { - if (GetFullType(field.value.type) == ftUnionValue) { - // Generate a match statement to handle unions properly. - code_.SetValue("KEY_TYPE", GenTableAccessorFuncReturnType(field, "")); - code_.SetValue("FIELD_TYPE_FIELD_NAME", field.name); - code_.SetValue("UNION_ERR", - "&\"InvalidFlatbuffer: Union discriminant" - " does not match value.\""); - - code_ += " match self.{{FIELD_NAME}}_type() {"; - ForAllUnionVariantsBesidesNone( - *field.value.type.enum_def, [&](const EnumVal &unused) { - (void)unused; - code_ += " {{U_ELEMENT_ENUM_TYPE}} => {"; - code_ += - " if let Some(x) = " - "self.{{FIELD_TYPE_FIELD_NAME}}_as_" - "{{U_ELEMENT_NAME}}() {"; - code_ += " ds.field(\"{{FIELD_NAME}}\", &x)"; - code_ += " } else {"; - code_ += - " ds.field(\"{{FIELD_NAME}}\", {{UNION_ERR}})"; - code_ += " }"; - code_ += " },"; - }); - code_ += " _ => {"; - code_ += " let x: Option<()> = None;"; - code_ += " ds.field(\"{{FIELD_NAME}}\", &x)"; - code_ += " },"; - code_ += " };"; - } else { - // Most fields. - code_ += " ds.field(\"{{FIELD_NAME}}\", &self.{{FIELD_NAME}}());"; - } - }); - code_ += " ds.finish()"; - code_ += " }"; - code_ += "}"; - } - - void GenTableObject(const StructDef &table) { - code_.SetValue("OBJECT_NAME", NativeName(table)); - code_.SetValue("STRUCT_NAME", Name(table)); - - // Generate the native object. - code_ += "#[non_exhaustive]"; - code_ += "#[derive(Debug, Clone, PartialEq)]"; - code_ += "pub struct {{OBJECT_NAME}} {"; - ForAllObjectTableFields(table, [&](const FieldDef &field) { - // Union objects combine both the union discriminant and value, so we - // skip making a field for the discriminant. - if (field.value.type.base_type == BASE_TYPE_UTYPE) return; - code_ += " pub {{FIELD_NAME}}: {{FIELD_OBJECT_TYPE}},"; - }); - code_ += "}"; - - code_ += "impl Default for {{OBJECT_NAME}} {"; - code_ += " fn default() -> Self {"; - code_ += " Self {"; - ForAllObjectTableFields(table, [&](const FieldDef &field) { - if (field.value.type.base_type == BASE_TYPE_UTYPE) return; - std::string default_value = GetDefaultValue(field, kObject); - code_ += " {{FIELD_NAME}}: " + default_value + ","; - }); - code_ += " }"; - code_ += " }"; - code_ += "}"; - - // TODO(cneo): Generate defaults for Native tables. However, since structs - // may be required, they, and therefore enums need defaults. - - // Generate pack function. - code_ += "impl {{OBJECT_NAME}} {"; - code_ += " pub fn pack<'b>("; - code_ += " &self,"; - code_ += " _fbb: &mut flatbuffers::FlatBufferBuilder<'b>"; - code_ += " ) -> flatbuffers::WIPOffset<{{STRUCT_NAME}}<'b>> {"; - // First we generate variables for each field and then later assemble them - // using "StructArgs" to more easily manage ownership of the builder. - ForAllObjectTableFields(table, [&](const FieldDef &field) { - const Type &type = field.value.type; - switch (GetFullType(type)) { - case ftInteger: - case ftBool: - case ftFloat: - case ftEnumKey: { - code_ += " let {{FIELD_NAME}} = self.{{FIELD_NAME}};"; - return; - } - case ftUnionKey: return; // Generate union type with union value. - case ftUnionValue: { - code_.SetValue("SNAKE_CASE_ENUM_NAME", - MakeSnakeCase(Name(*field.value.type.enum_def))); - code_ += - " let {{FIELD_NAME}}_type = " - "self.{{FIELD_NAME}}.{{SNAKE_CASE_ENUM_NAME}}_type();"; - code_ += " let {{FIELD_NAME}} = self.{{FIELD_NAME}}.pack(_fbb);"; - return; - } - // The rest of the types require special casing around optionalness - // due to "required" annotation. - case ftString: { - MapNativeTableField(field, "_fbb.create_string(x)"); - return; - } - case ftStruct: { - // Hold the struct in a variable so we can reference it. - if (field.IsRequired()) { - code_ += - " let {{FIELD_NAME}}_tmp = " - "Some(self.{{FIELD_NAME}}.pack());"; - } else { - code_ += - " let {{FIELD_NAME}}_tmp = self.{{FIELD_NAME}}" - ".as_ref().map(|x| x.pack());"; - } - code_ += " let {{FIELD_NAME}} = {{FIELD_NAME}}_tmp.as_ref();"; - - return; - } - case ftTable: { - MapNativeTableField(field, "x.pack(_fbb)"); - return; - } - case ftVectorOfEnumKey: - case ftVectorOfInteger: - case ftVectorOfBool: - case ftVectorOfFloat: { - MapNativeTableField(field, "_fbb.create_vector(x)"); - return; - } - case ftVectorOfStruct: { - MapNativeTableField( - field, - "let w: Vec<_> = x.iter().map(|t| t.pack()).collect();" - "_fbb.create_vector(&w)"); - return; - } - case ftVectorOfString: { - // TODO(cneo): create_vector* should be more generic to avoid - // allocations. - - MapNativeTableField( - field, - "let w: Vec<_> = x.iter().map(|s| s.as_ref()).collect();" - "_fbb.create_vector_of_strings(&w)"); - return; - } - case ftVectorOfTable: { - MapNativeTableField( - field, - "let w: Vec<_> = x.iter().map(|t| t.pack(_fbb)).collect();" - "_fbb.create_vector(&w)"); - return; - } - case ftVectorOfUnionValue: { - FLATBUFFERS_ASSERT(false && "vectors of unions not yet supported"); - return; - } - case ftArrayOfEnum: - case ftArrayOfStruct: - case ftArrayOfBuiltin: { - FLATBUFFERS_ASSERT(false && "arrays are not supported within tables"); - return; - } - } - }); - code_ += " {{STRUCT_NAME}}::create(_fbb, &{{STRUCT_NAME}}Args{"; - ForAllObjectTableFields(table, [&](const FieldDef &field) { - (void)field; // Unused. - code_ += " {{FIELD_NAME}},"; - }); - code_ += " })"; - code_ += " }"; - code_ += "}"; - } - void ForAllObjectTableFields(const StructDef &table, - std::function<void(const FieldDef &)> cb) { - const std::vector<FieldDef *> &v = table.fields.vec; - for (auto it = v.begin(); it != v.end(); it++) { - const FieldDef &field = **it; - if (field.deprecated) continue; - code_.SetValue("FIELD_NAME", Name(field)); - code_.SetValue("FIELD_OBJECT_TYPE", ObjectFieldType(field, true)); - cb(field); - } - } - void MapNativeTableField(const FieldDef &field, const std::string &expr) { - if (field.IsOptional()) { - code_ += " let {{FIELD_NAME}} = self.{{FIELD_NAME}}.as_ref().map(|x|{"; - code_ += " " + expr; - code_ += " });"; - } else { - // For some reason Args has optional types for required fields. - // TODO(cneo): Fix this... but its a breaking change? - code_ += " let {{FIELD_NAME}} = Some({"; - code_ += " let x = &self.{{FIELD_NAME}};"; - code_ += " " + expr; - code_ += " });"; - } - } - - // Generate functions to compare tables and structs by key. This function - // must only be called if the field key is defined. - void GenKeyFieldMethods(const FieldDef &field) { - FLATBUFFERS_ASSERT(field.key); - - code_.SetValue("KEY_TYPE", GenTableAccessorFuncReturnType(field, "")); - - code_ += " #[inline]"; - code_ += - " pub fn key_compare_less_than(&self, o: &{{STRUCT_NAME}}) -> " - " bool {"; - code_ += " self.{{FIELD_NAME}}() < o.{{FIELD_NAME}}()"; - code_ += " }"; - code_ += ""; - code_ += " #[inline]"; - code_ += - " pub fn key_compare_with_value(&self, val: {{KEY_TYPE}}) -> " - " ::std::cmp::Ordering {"; - code_ += " let key = self.{{FIELD_NAME}}();"; - code_ += " key.cmp(&val)"; - code_ += " }"; - } - - // Generate functions for accessing the root table object. This function - // must only be called if the root table is defined. - void GenRootTableFuncs(const StructDef &struct_def) { - FLATBUFFERS_ASSERT(parser_.root_struct_def_ && "root table not defined"); - auto name = Name(struct_def); - - code_.SetValue("STRUCT_NAME", name); - code_.SetValue("STRUCT_NAME_SNAKECASE", MakeSnakeCase(name)); - code_.SetValue("STRUCT_NAME_CAPS", MakeUpper(MakeSnakeCase(name))); - - // The root datatype accessors: - code_ += "#[inline]"; - code_ += - "#[deprecated(since=\"2.0.0\", " - "note=\"Deprecated in favor of `root_as...` methods.\")]"; - code_ += - "pub fn get_root_as_{{STRUCT_NAME_SNAKECASE}}<'a>(buf: &'a [u8])" - " -> {{STRUCT_NAME}}<'a> {"; - code_ += - " unsafe { flatbuffers::root_unchecked::<{{STRUCT_NAME}}" - "<'a>>(buf) }"; - code_ += "}"; - code_ += ""; - - code_ += "#[inline]"; - code_ += - "#[deprecated(since=\"2.0.0\", " - "note=\"Deprecated in favor of `root_as...` methods.\")]"; - code_ += - "pub fn get_size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}" - "<'a>(buf: &'a [u8]) -> {{STRUCT_NAME}}<'a> {"; - code_ += - " unsafe { flatbuffers::size_prefixed_root_unchecked::<{{STRUCT_NAME}}" - "<'a>>(buf) }"; - code_ += "}"; - code_ += ""; - // Default verifier root fns. - code_ += "#[inline]"; - code_ += "/// Verifies that a buffer of bytes contains a `{{STRUCT_NAME}}`"; - code_ += "/// and returns it."; - code_ += "/// Note that verification is still experimental and may not"; - code_ += "/// catch every error, or be maximally performant. For the"; - code_ += "/// previous, unchecked, behavior use"; - code_ += "/// `root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked`."; - code_ += - "pub fn root_as_{{STRUCT_NAME_SNAKECASE}}(buf: &[u8]) " - "-> Result<{{STRUCT_NAME}}, flatbuffers::InvalidFlatbuffer> {"; - code_ += " flatbuffers::root::<{{STRUCT_NAME}}>(buf)"; - code_ += "}"; - code_ += "#[inline]"; - code_ += "/// Verifies that a buffer of bytes contains a size prefixed"; - code_ += "/// `{{STRUCT_NAME}}` and returns it."; - code_ += "/// Note that verification is still experimental and may not"; - code_ += "/// catch every error, or be maximally performant. For the"; - code_ += "/// previous, unchecked, behavior use"; - code_ += "/// `size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked`."; - code_ += - "pub fn size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}" - "(buf: &[u8]) -> Result<{{STRUCT_NAME}}, " - "flatbuffers::InvalidFlatbuffer> {"; - code_ += " flatbuffers::size_prefixed_root::<{{STRUCT_NAME}}>(buf)"; - code_ += "}"; - // Verifier with options root fns. - code_ += "#[inline]"; - code_ += "/// Verifies, with the given options, that a buffer of bytes"; - code_ += "/// contains a `{{STRUCT_NAME}}` and returns it."; - code_ += "/// Note that verification is still experimental and may not"; - code_ += "/// catch every error, or be maximally performant. For the"; - code_ += "/// previous, unchecked, behavior use"; - code_ += "/// `root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked`."; - code_ += "pub fn root_as_{{STRUCT_NAME_SNAKECASE}}_with_opts<'b, 'o>("; - code_ += " opts: &'o flatbuffers::VerifierOptions,"; - code_ += " buf: &'b [u8],"; - code_ += - ") -> Result<{{STRUCT_NAME}}<'b>, flatbuffers::InvalidFlatbuffer>" - " {"; - code_ += " flatbuffers::root_with_opts::<{{STRUCT_NAME}}<'b>>(opts, buf)"; - code_ += "}"; - code_ += "#[inline]"; - code_ += "/// Verifies, with the given verifier options, that a buffer of"; - code_ += "/// bytes contains a size prefixed `{{STRUCT_NAME}}` and returns"; - code_ += "/// it. Note that verification is still experimental and may not"; - code_ += "/// catch every error, or be maximally performant. For the"; - code_ += "/// previous, unchecked, behavior use"; - code_ += "/// `root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked`."; - code_ += - "pub fn size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}_with_opts" - "<'b, 'o>("; - code_ += " opts: &'o flatbuffers::VerifierOptions,"; - code_ += " buf: &'b [u8],"; - code_ += - ") -> Result<{{STRUCT_NAME}}<'b>, flatbuffers::InvalidFlatbuffer>" - " {"; - code_ += - " flatbuffers::size_prefixed_root_with_opts::<{{STRUCT_NAME}}" - "<'b>>(opts, buf)"; - code_ += "}"; - // Unchecked root fns. - code_ += "#[inline]"; - code_ += - "/// Assumes, without verification, that a buffer of bytes " - "contains a {{STRUCT_NAME}} and returns it."; - code_ += "/// # Safety"; - code_ += - "/// Callers must trust the given bytes do indeed contain a valid" - " `{{STRUCT_NAME}}`."; - code_ += - "pub unsafe fn root_as_{{STRUCT_NAME_SNAKECASE}}_unchecked" - "(buf: &[u8]) -> {{STRUCT_NAME}} {"; - code_ += " flatbuffers::root_unchecked::<{{STRUCT_NAME}}>(buf)"; - code_ += "}"; - code_ += "#[inline]"; - code_ += - "/// Assumes, without verification, that a buffer of bytes " - "contains a size prefixed {{STRUCT_NAME}} and returns it."; - code_ += "/// # Safety"; - code_ += - "/// Callers must trust the given bytes do indeed contain a valid" - " size prefixed `{{STRUCT_NAME}}`."; - code_ += - "pub unsafe fn size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}" - "_unchecked(buf: &[u8]) -> {{STRUCT_NAME}} {"; - code_ += - " flatbuffers::size_prefixed_root_unchecked::<{{STRUCT_NAME}}>" - "(buf)"; - code_ += "}"; - - if (parser_.file_identifier_.length()) { - // Declare the identifier - // (no lifetime needed as constants have static lifetimes by default) - code_ += "pub const {{STRUCT_NAME_CAPS}}_IDENTIFIER: &str\\"; - code_ += " = \"" + parser_.file_identifier_ + "\";"; - code_ += ""; - - // Check if a buffer has the identifier. - code_ += "#[inline]"; - code_ += "pub fn {{STRUCT_NAME_SNAKECASE}}_buffer_has_identifier\\"; - code_ += "(buf: &[u8]) -> bool {"; - code_ += " flatbuffers::buffer_has_identifier(buf, \\"; - code_ += "{{STRUCT_NAME_CAPS}}_IDENTIFIER, false)"; - code_ += "}"; - code_ += ""; - code_ += "#[inline]"; - code_ += "pub fn {{STRUCT_NAME_SNAKECASE}}_size_prefixed\\"; - code_ += "_buffer_has_identifier(buf: &[u8]) -> bool {"; - code_ += " flatbuffers::buffer_has_identifier(buf, \\"; - code_ += "{{STRUCT_NAME_CAPS}}_IDENTIFIER, true)"; - code_ += "}"; - code_ += ""; - } - - if (parser_.file_extension_.length()) { - // Return the extension - code_ += "pub const {{STRUCT_NAME_CAPS}}_EXTENSION: &str = \\"; - code_ += "\"" + parser_.file_extension_ + "\";"; - code_ += ""; - } - - // Finish a buffer with a given root object: - code_.SetValue("OFFSET_TYPELABEL", Name(struct_def) + "Offset"); - code_ += "#[inline]"; - code_ += "pub fn finish_{{STRUCT_NAME_SNAKECASE}}_buffer<'a, 'b>("; - code_ += " fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,"; - code_ += " root: flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>>) {"; - if (parser_.file_identifier_.length()) { - code_ += " fbb.finish(root, Some({{STRUCT_NAME_CAPS}}_IDENTIFIER));"; - } else { - code_ += " fbb.finish(root, None);"; - } - code_ += "}"; - code_ += ""; - code_ += "#[inline]"; - code_ += - "pub fn finish_size_prefixed_{{STRUCT_NAME_SNAKECASE}}_buffer" - "<'a, 'b>(" - "fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, " - "root: flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>>) {"; - if (parser_.file_identifier_.length()) { - code_ += - " fbb.finish_size_prefixed(root, " - "Some({{STRUCT_NAME_CAPS}}_IDENTIFIER));"; - } else { - code_ += " fbb.finish_size_prefixed(root, None);"; - } - code_ += "}"; - } - - static void GenPadding( - const FieldDef &field, std::string *code_ptr, int *id, - const std::function<void(int bits, std::string *code_ptr, int *id)> &f) { - if (field.padding) { - for (int i = 0; i < 4; i++) { - if (static_cast<int>(field.padding) & (1 << i)) { - f((1 << i) * 8, code_ptr, id); - } - } - assert(!(field.padding & ~0xF)); - } - } - - static void PaddingDefinition(int bits, std::string *code_ptr, int *id) { - *code_ptr += - " padding" + NumToString((*id)++) + "__: u" + NumToString(bits) + ","; - } - - static void PaddingInitializer(int bits, std::string *code_ptr, int *id) { - (void)bits; - *code_ptr += "padding" + NumToString((*id)++) + "__: 0,"; - } - - void ForAllStructFields(const StructDef &struct_def, - std::function<void(const FieldDef &field)> cb) { - size_t offset_to_field = 0; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - code_.SetValue("FIELD_TYPE", GetTypeGet(field.value.type)); - code_.SetValue("FIELD_OBJECT_TYPE", ObjectFieldType(field, false)); - code_.SetValue("FIELD_NAME", Name(field)); - code_.SetValue("FIELD_OFFSET", NumToString(offset_to_field)); - code_.SetValue( - "REF", - IsStruct(field.value.type) || IsArray(field.value.type) ? "&" : ""); - cb(field); - const size_t size = InlineSize(field.value.type); - offset_to_field += size + field.padding; - } - } - // Generate an accessor struct with constructor for a flatbuffers struct. - void GenStruct(const StructDef &struct_def) { - // Generates manual padding and alignment. - // Variables are private because they contain little endian data on all - // platforms. - GenComment(struct_def.doc_comment); - code_.SetValue("ALIGN", NumToString(struct_def.minalign)); - code_.SetValue("STRUCT_NAME", Name(struct_def)); - code_.SetValue("STRUCT_SIZE", NumToString(struct_def.bytesize)); - - // We represent Flatbuffers-structs in Rust-u8-arrays since the data may be - // of the wrong endianness and alignment 1. - // - // PartialEq is useful to derive because we can correctly compare structs - // for equality by just comparing their underlying byte data. This doesn't - // hold for PartialOrd/Ord. - code_ += "// struct {{STRUCT_NAME}}, aligned to {{ALIGN}}"; - code_ += "#[repr(transparent)]"; - code_ += "#[derive(Clone, Copy, PartialEq)]"; - code_ += "pub struct {{STRUCT_NAME}}(pub [u8; {{STRUCT_SIZE}}]);"; - code_ += "impl Default for {{STRUCT_NAME}} { "; - code_ += " fn default() -> Self { "; - code_ += " Self([0; {{STRUCT_SIZE}}])"; - code_ += " }"; - code_ += "}"; - - // Debug for structs. - code_ += "impl std::fmt::Debug for {{STRUCT_NAME}} {"; - code_ += - " fn fmt(&self, f: &mut std::fmt::Formatter" - ") -> std::fmt::Result {"; - code_ += " f.debug_struct(\"{{STRUCT_NAME}}\")"; - ForAllStructFields(struct_def, [&](const FieldDef &unused) { - (void)unused; - code_ += " .field(\"{{FIELD_NAME}}\", &self.{{FIELD_NAME}}())"; - }); - code_ += " .finish()"; - code_ += " }"; - code_ += "}"; - code_ += ""; - - // Generate impls for SafeSliceAccess (because all structs are endian-safe), - // Follow for the value type, Follow for the reference type, Push for the - // value type, and Push for the reference type. - code_ += "impl flatbuffers::SimpleToVerifyInSlice for {{STRUCT_NAME}} {}"; - code_ += "impl flatbuffers::SafeSliceAccess for {{STRUCT_NAME}} {}"; - code_ += "impl<'a> flatbuffers::Follow<'a> for {{STRUCT_NAME}} {"; - code_ += " type Inner = &'a {{STRUCT_NAME}};"; - code_ += " #[inline]"; - code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; - code_ += " <&'a {{STRUCT_NAME}}>::follow(buf, loc)"; - code_ += " }"; - code_ += "}"; - code_ += "impl<'a> flatbuffers::Follow<'a> for &'a {{STRUCT_NAME}} {"; - code_ += " type Inner = &'a {{STRUCT_NAME}};"; - code_ += " #[inline]"; - code_ += " fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; - code_ += " flatbuffers::follow_cast_ref::<{{STRUCT_NAME}}>(buf, loc)"; - code_ += " }"; - code_ += "}"; - code_ += "impl<'b> flatbuffers::Push for {{STRUCT_NAME}} {"; - code_ += " type Output = {{STRUCT_NAME}};"; - code_ += " #[inline]"; - code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {"; - code_ += " let src = unsafe {"; - code_ += - " ::std::slice::from_raw_parts(" - "self as *const {{STRUCT_NAME}} as *const u8, Self::size())"; - code_ += " };"; - code_ += " dst.copy_from_slice(src);"; - code_ += " }"; - code_ += "}"; - code_ += "impl<'b> flatbuffers::Push for &'b {{STRUCT_NAME}} {"; - code_ += " type Output = {{STRUCT_NAME}};"; - code_ += ""; - code_ += " #[inline]"; - code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {"; - code_ += " let src = unsafe {"; - code_ += - " ::std::slice::from_raw_parts(" - "*self as *const {{STRUCT_NAME}} as *const u8, Self::size())"; - code_ += " };"; - code_ += " dst.copy_from_slice(src);"; - code_ += " }"; - code_ += "}"; - code_ += ""; - - // Generate verifier: Structs are simple so presence and alignment are - // all that need to be checked. - code_ += "impl<'a> flatbuffers::Verifiable for {{STRUCT_NAME}} {"; - code_ += " #[inline]"; - code_ += " fn run_verifier("; - code_ += " v: &mut flatbuffers::Verifier, pos: usize"; - code_ += " ) -> Result<(), flatbuffers::InvalidFlatbuffer> {"; - code_ += " use self::flatbuffers::Verifiable;"; - code_ += " v.in_buffer::<Self>(pos)"; - code_ += " }"; - code_ += "}"; - - // Generate a constructor that takes all fields as arguments. - code_ += "impl<'a> {{STRUCT_NAME}} {"; - code_ += " #[allow(clippy::too_many_arguments)]"; - code_ += " pub fn new("; - ForAllStructFields(struct_def, [&](const FieldDef &unused) { - (void)unused; - code_ += " {{FIELD_NAME}}: {{REF}}{{FIELD_TYPE}},"; - }); - code_ += " ) -> Self {"; - code_ += " let mut s = Self([0; {{STRUCT_SIZE}}]);"; - ForAllStructFields(struct_def, [&](const FieldDef &unused) { - (void)unused; - code_ += " s.set_{{FIELD_NAME}}({{REF}}{{FIELD_NAME}});"; - }); - code_ += " s"; - code_ += " }"; - code_ += ""; - - if (parser_.opts.generate_name_strings) { - GenFullyQualifiedNameGetter(struct_def, struct_def.name); - } - - // Generate accessor methods for the struct. - ForAllStructFields(struct_def, [&](const FieldDef &field) { - this->GenComment(field.doc_comment, " "); - // Getter. - if (IsStruct(field.value.type)) { - code_ += " pub fn {{FIELD_NAME}}(&self) -> &{{FIELD_TYPE}} {"; - code_ += - " unsafe {" - " &*(self.0[{{FIELD_OFFSET}}..].as_ptr() as *const" - " {{FIELD_TYPE}}) }"; - } else if (IsArray(field.value.type)) { - code_.SetValue("ARRAY_SIZE", - NumToString(field.value.type.fixed_length)); - code_.SetValue("ARRAY_ITEM", GetTypeGet(field.value.type.VectorType())); - code_ += - " pub fn {{FIELD_NAME}}(&'a self) -> " - "flatbuffers::Array<'a, {{ARRAY_ITEM}}, {{ARRAY_SIZE}}> {"; - code_ += " flatbuffers::Array::follow(&self.0, {{FIELD_OFFSET}})"; - } else { - code_ += " pub fn {{FIELD_NAME}}(&self) -> {{FIELD_TYPE}} {"; - code_ += - " let mut mem = core::mem::MaybeUninit::" - "<{{FIELD_TYPE}}>::uninit();"; - code_ += " unsafe {"; - code_ += " core::ptr::copy_nonoverlapping("; - code_ += " self.0[{{FIELD_OFFSET}}..].as_ptr(),"; - code_ += " mem.as_mut_ptr() as *mut u8,"; - code_ += " core::mem::size_of::<{{FIELD_TYPE}}>(),"; - code_ += " );"; - code_ += " mem.assume_init()"; - code_ += " }.from_little_endian()"; - } - code_ += " }\n"; - // Setter. - if (IsStruct(field.value.type)) { - code_.SetValue("FIELD_SIZE", NumToString(InlineSize(field.value.type))); - code_ += " pub fn set_{{FIELD_NAME}}(&mut self, x: &{{FIELD_TYPE}}) {"; - code_ += - " self.0[{{FIELD_OFFSET}}..{{FIELD_OFFSET}}+{{FIELD_SIZE}}]" - ".copy_from_slice(&x.0)"; - } else if (IsArray(field.value.type)) { - if (GetFullType(field.value.type) == ftArrayOfBuiltin) { - code_.SetValue("ARRAY_ITEM", - GetTypeGet(field.value.type.VectorType())); - code_.SetValue( - "ARRAY_ITEM_SIZE", - NumToString(InlineSize(field.value.type.VectorType()))); - code_ += - " pub fn set_{{FIELD_NAME}}(&mut self, items: &{{FIELD_TYPE}}) " - "{"; - code_ += - " flatbuffers::emplace_scalar_array(&mut self.0, " - "{{FIELD_OFFSET}}, items);"; - } else { - code_.SetValue("FIELD_SIZE", - NumToString(InlineSize(field.value.type))); - code_ += - " pub fn set_{{FIELD_NAME}}(&mut self, x: &{{FIELD_TYPE}}) {"; - code_ += " unsafe {"; - code_ += " std::ptr::copy("; - code_ += " x.as_ptr() as *const u8,"; - code_ += " self.0.as_mut_ptr().add({{FIELD_OFFSET}}),"; - code_ += " {{FIELD_SIZE}},"; - code_ += " );"; - code_ += " }"; - } - } else { - code_ += " pub fn set_{{FIELD_NAME}}(&mut self, x: {{FIELD_TYPE}}) {"; - code_ += " let x_le = x.to_little_endian();"; - code_ += " unsafe {"; - code_ += " core::ptr::copy_nonoverlapping("; - code_ += " &x_le as *const {{FIELD_TYPE}} as *const u8,"; - code_ += " self.0[{{FIELD_OFFSET}}..].as_mut_ptr(),"; - code_ += " core::mem::size_of::<{{FIELD_TYPE}}>(),"; - code_ += " );"; - code_ += " }"; - } - code_ += " }\n"; - - // Generate a comparison function for this field if it is a key. - if (field.key) { GenKeyFieldMethods(field); } - }); - - // Generate Object API unpack method. - if (parser_.opts.generate_object_based_api) { - code_.SetValue("NATIVE_STRUCT_NAME", NativeName(struct_def)); - code_ += " pub fn unpack(&self) -> {{NATIVE_STRUCT_NAME}} {"; - code_ += " {{NATIVE_STRUCT_NAME}} {"; - ForAllStructFields(struct_def, [&](const FieldDef &field) { - if (IsArray(field.value.type)) { - if (GetFullType(field.value.type) == ftArrayOfStruct) { - code_ += - " {{FIELD_NAME}}: { let {{FIELD_NAME}} = " - "self.{{FIELD_NAME}}(); flatbuffers::array_init(|i| " - "{{FIELD_NAME}}.get(i).unpack()) },"; - } else { - code_ += " {{FIELD_NAME}}: self.{{FIELD_NAME}}().into(),"; - } - } else { - std::string unpack = IsStruct(field.value.type) ? ".unpack()" : ""; - code_ += " {{FIELD_NAME}}: self.{{FIELD_NAME}}()" + unpack + ","; - } - }); - code_ += " }"; - code_ += " }"; - } - - code_ += "}"; // End impl Struct methods. - code_ += ""; - - // Generate Struct Object. - if (parser_.opts.generate_object_based_api) { - // Struct declaration - code_ += "#[derive(Debug, Clone, PartialEq, Default)]"; - code_ += "pub struct {{NATIVE_STRUCT_NAME}} {"; - ForAllStructFields(struct_def, [&](const FieldDef &field) { - (void)field; // unused. - code_ += " pub {{FIELD_NAME}}: {{FIELD_OBJECT_TYPE}},"; - }); - code_ += "}"; - // The `pack` method that turns the native struct into its Flatbuffers - // counterpart. - code_ += "impl {{NATIVE_STRUCT_NAME}} {"; - code_ += " pub fn pack(&self) -> {{STRUCT_NAME}} {"; - code_ += " {{STRUCT_NAME}}::new("; - ForAllStructFields(struct_def, [&](const FieldDef &field) { - if (IsStruct(field.value.type)) { - code_ += " &self.{{FIELD_NAME}}.pack(),"; - } else if (IsArray(field.value.type)) { - if (GetFullType(field.value.type) == ftArrayOfStruct) { - code_ += - " &flatbuffers::array_init(|i| " - "self.{{FIELD_NAME}}[i].pack()),"; - } else { - code_ += " &self.{{FIELD_NAME}},"; - } - } else { - code_ += " self.{{FIELD_NAME}},"; - } - }); - code_ += " )"; - code_ += " }"; - code_ += "}"; - code_ += ""; - } - } - - void GenNamespaceImports(const int white_spaces) { - // DO not use global attributes (i.e. #![...]) since it interferes - // with users who include! generated files. - // See: https://github.com/google/flatbuffers/issues/6261 - std::string indent = std::string(white_spaces, ' '); - code_ += ""; - if (!parser_.opts.generate_all) { - for (auto it = parser_.included_files_.begin(); - it != parser_.included_files_.end(); ++it) { - if (it->second.empty()) continue; - auto noext = flatbuffers::StripExtension(it->second); - auto basename = flatbuffers::StripPath(noext); - - if (parser_.opts.include_prefix.empty()) { - code_ += indent + "use crate::" + basename + - parser_.opts.filename_suffix + "::*;"; - } else { - auto prefix = parser_.opts.include_prefix; - prefix.pop_back(); - - code_ += indent + "use crate::" + prefix + "::" + basename + - parser_.opts.filename_suffix + "::*;"; - } - } - } - code_ += indent + "use std::mem;"; - code_ += indent + "use std::cmp::Ordering;"; - code_ += ""; - code_ += indent + "extern crate flatbuffers;"; - code_ += indent + "use self::flatbuffers::{EndianScalar, Follow};"; - } - - // Set up the correct namespace. This opens a namespace if the current - // namespace is different from the target namespace. This function - // closes and opens the namespaces only as necessary. - // - // The file must start and end with an empty (or null) namespace so that - // namespaces are properly opened and closed. - void SetNameSpace(const Namespace *ns) { - if (cur_name_space_ == ns) { return; } - - // Compute the size of the longest common namespace prefix. - // If cur_name_space is A::B::C::D and ns is A::B::E::F::G, - // the common prefix is A::B:: and we have old_size = 4, new_size = 5 - // and common_prefix_size = 2 - size_t old_size = cur_name_space_ ? cur_name_space_->components.size() : 0; - size_t new_size = ns ? ns->components.size() : 0; - - size_t common_prefix_size = 0; - while (common_prefix_size < old_size && common_prefix_size < new_size && - ns->components[common_prefix_size] == - cur_name_space_->components[common_prefix_size]) { - common_prefix_size++; - } - - // Close cur_name_space in reverse order to reach the common prefix. - // In the previous example, D then C are closed. - for (size_t j = old_size; j > common_prefix_size; --j) { - code_ += "} // pub mod " + cur_name_space_->components[j - 1]; - } - if (old_size != common_prefix_size) { code_ += ""; } - - // open namespace parts to reach the ns namespace - // in the previous example, E, then F, then G are opened - for (auto j = common_prefix_size; j != new_size; ++j) { - code_ += "#[allow(unused_imports, dead_code)]"; - code_ += "pub mod " + MakeSnakeCase(ns->components[j]) + " {"; - // Generate local namespace imports. - GenNamespaceImports(2); - } - if (new_size != common_prefix_size) { code_ += ""; } - - cur_name_space_ = ns; - } -}; - -} // namespace rust - -bool GenerateRust(const Parser &parser, const std::string &path, - const std::string &file_name) { - rust::RustGenerator generator(parser, path, file_name); - return generator.generate(); -} - -std::string RustMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name) { - std::string filebase = - flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); - rust::RustGenerator generator(parser, path, file_name); - std::string make_rule = - generator.GeneratedFileName(path, filebase, parser.opts) + ": "; - - auto included_files = parser.GetIncludedFilesRecursive(file_name); - for (auto it = included_files.begin(); it != included_files.end(); ++it) { - make_rule += " " + *it; - } - return make_rule; -} - -} // namespace flatbuffers - -// TODO(rw): Generated code should import other generated files. -// TODO(rw): Generated code should refer to namespaces in included files in a -// way that makes them referrable. -// TODO(rw): Generated code should indent according to nesting level. -// TODO(rw): Generated code should generate endian-safe Debug impls. -// TODO(rw): Generated code could use a Rust-only enum type to access unions, -// instead of making the user use _type() to manually switch. -// TODO(maxburke): There should be test schemas added that use language -// keywords as fields of structs, tables, unions, enums, to make sure -// that internal code generated references escaped names correctly. -// TODO(maxburke): We should see if there is a more flexible way of resolving -// module paths for use declarations. Right now if schemas refer to -// other flatbuffer files, the include paths in emitted Rust bindings -// are crate-relative which may undesirable. diff --git a/contrib/libs/flatbuffers/src/idl_gen_swift.cpp b/contrib/libs/flatbuffers/src/idl_gen_swift.cpp deleted file mode 100644 index 3fffd39455..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_swift.cpp +++ /dev/null @@ -1,1575 +0,0 @@ -/* - * 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 - * - * 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 <cctype> -#include <unordered_set> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -namespace swift { - -inline std::string GenIndirect(const std::string &reading) { - return "{{ACCESS}}.indirect(" + reading + ")"; -} - -inline std::string GenArrayMainBody(const std::string &optional) { - return "{{ACCESS_TYPE}} func {{VALUENAME}}(at index: Int32) -> " - "{{VALUETYPE}}" + - optional + " { "; -} - -class SwiftGenerator : public BaseGenerator { - private: - CodeWriter code_; - std::unordered_set<std::string> keywords_; - int namespace_depth; - - public: - SwiftGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", "_", "swift") { - namespace_depth = 0; - code_.SetPadding(" "); - static const char *const keywords[] = { - "associatedtype", - "class", - "deinit", - "enum", - "extension", - "fileprivate", - "func", - "import", - "init", - "inout", - "internal", - "let", - "open", - "operator", - "private", - "protocol", - "public", - "rethrows", - "static", - "struct", - "subscript", - "typealias", - "var", - "break", - "case", - "continue", - "default", - "defer", - "do", - "else", - "fallthrough", - "for", - "guard", - "if", - "in", - "repeat", - "return", - "switch", - "where", - "while", - "Any", - "catch", - "false", - "is", - "nil", - "super", - "self", - "Self", - "throw", - "throws", - "true", - "try", - "associativity", - "convenience", - "dynamic", - "didSet", - "final", - "get", - "infix", - "indirect", - "lazy", - "left", - "mutating", - "none", - "nonmutating", - "optional", - "override", - "postfix", - "precedence", - "prefix", - "Protocol", - "required", - "right", - "set", - "Type", - "unowned", - "weak", - "willSet", - "Void", - nullptr, - }; - for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw); - } - - bool generate() { - code_.Clear(); - code_.SetValue("ACCESS", "_accessor"); - code_.SetValue("TABLEOFFSET", "VTOFFSET"); - code_ += "// " + std::string(FlatBuffersGeneratedWarning()); - code_ += "// swiftlint:disable all"; - code_ += "// swiftformat:disable all\n"; - code_ += "import FlatBuffers\n"; - // Generate code for all the enum declarations. - - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - const auto &enum_def = **it; - if (!enum_def.generated) { GenEnum(enum_def); } - } - - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (struct_def.fixed && !struct_def.generated) { - GenStructReader(struct_def); - GenMutableStructReader(struct_def); - } - } - - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - const auto &struct_def = **it; - if (!struct_def.fixed && !struct_def.generated) { - GenTable(struct_def); - if (parser_.opts.generate_object_based_api) { - GenObjectAPI(struct_def); - } - } - } - - const auto filename = GeneratedFileName(path_, file_name_, parser_.opts); - const auto final_code = code_.ToString(); - return SaveFile(filename.c_str(), final_code, false); - } - - void mark(const std::string &str) { - code_.SetValue("MARKVALUE", str); - code_ += "\n// MARK: - {{MARKVALUE}}\n"; - } - - // MARK: - Generating structs - - // Generates the reader for swift - void GenStructReader(const StructDef &struct_def) { - auto is_private_access = struct_def.attributes.Lookup("private"); - code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public"); - GenComment(struct_def.doc_comment); - code_.SetValue("STRUCTNAME", NameWrappedInNameSpace(struct_def)); - code_ += "{{ACCESS_TYPE}} struct {{STRUCTNAME}}: NativeStruct\\"; - if (parser_.opts.generate_object_based_api) code_ += ", NativeObject\\"; - code_ += " {"; - code_ += ""; - Indent(); - code_ += ValidateFunc(); - code_ += ""; - int padding_id = 0; - std::string constructor = ""; - std::vector<std::string> base_constructor; - std::vector<std::string> main_constructor; - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - if (!constructor.empty()) constructor += ", "; - - auto name = Name(field); - auto type = GenType(field.value.type); - code_.SetValue("VALUENAME", name); - if (IsEnum(field.value.type)) { - code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false)); - } - code_.SetValue("VALUETYPE", type); - GenComment(field.doc_comment); - std::string valueType = - 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; - - main_constructor.push_back("_" + name + " = " + name + accessing_value); - base_constructor.push_back("_" + name + " = " + base_value); - - if (field.padding) { GenPadding(field, &padding_id); } - constructor += name + ": " + type; - } - code_ += ""; - BuildObjectConstructor(main_constructor, constructor); - BuildObjectConstructor(base_constructor, ""); - - if (parser_.opts.generate_object_based_api) - GenerateObjectAPIStructConstructor(struct_def); - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto name = Name(field); - auto type = GenType(field.value.type); - code_.SetValue("VALUENAME", name); - code_.SetValue("VALUETYPE", type); - GenComment(field.doc_comment); - if (!IsEnum(field.value.type)) { - code_ += GenReaderMainBody() + "_{{VALUENAME}} }"; - } else if (IsEnum(field.value.type)) { - code_ += - GenReaderMainBody() + "{{VALUETYPE}}(rawValue: _{{VALUENAME}})! }"; - } - } - Outdent(); - code_ += "}\n"; - } - - void GenMutableStructReader(const StructDef &struct_def) { - GenObjectHeader(struct_def); - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto offset = NumToString(field.value.offset); - auto name = Name(field); - auto type = GenType(field.value.type); - code_.SetValue("VALUENAME", name); - if (IsEnum(field.value.type)) { - code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false)); - } - code_.SetValue("VALUETYPE", type); - code_.SetValue("OFFSET", offset); - if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type)) { - code_ += - GenReaderMainBody() + "return " + GenReader("VALUETYPE") + " }"; - } else if (IsEnum(field.value.type)) { - code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false)); - code_ += GenReaderMainBody() + "return " + - GenEnumConstructor("{{OFFSET}}") + "?? " + - GenEnumDefaultValue(field) + " }"; - } else if (IsStruct(field.value.type)) { - code_.SetValue("VALUETYPE", GenType(field.value.type) + Mutable()); - code_ += GenReaderMainBody() + "return " + - GenConstructor("{{ACCESS}}.postion + {{OFFSET}}"); - } - if (parser_.opts.mutable_buffer && !IsStruct(field.value.type)) - code_ += GenMutate("{{OFFSET}}", "", IsEnum(field.value.type)); - } - - if (parser_.opts.generate_object_based_api) { - GenerateObjectAPIExtensionHeader(NameWrappedInNameSpace(struct_def)); - code_ += "return builder.create(struct: obj)"; - Outdent(); - code_ += "}"; - } - Outdent(); - code_ += "}\n"; - } - - // Generates the create function for swift - void GenStructWriter(const StructDef &struct_def) { - auto is_private_access = struct_def.attributes.Lookup("private"); - code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public"); - code_.SetValue("STRUCTNAME", NameWrappedInNameSpace(struct_def)); - code_.SetValue("SHORT_STRUCTNAME", Name(struct_def)); - code_ += "extension {{STRUCTNAME}} {"; - Indent(); - code_ += "@discardableResult"; - code_ += - "{{ACCESS_TYPE}} static func create{{SHORT_STRUCTNAME}}(builder: inout " - "FlatBufferBuilder, \\"; - std::string func_header = ""; - GenerateStructArgs(struct_def, &func_header, "", ""); - code_ += func_header.substr(0, func_header.size() - 2) + "\\"; - code_ += ") -> Offset {"; - Indent(); - code_ += - "builder.createStructOf(size: {{STRUCTNAME}}.size, alignment: " - "{{STRUCTNAME}}.alignment)"; - code_ += "return builder.endStruct()"; - Outdent(); - code_ += "}\n"; - Outdent(); - code_ += "}\n"; - } - - void GenerateStructArgs(const StructDef &struct_def, std::string *code_ptr, - const std::string &nameprefix, - const std::string &object_name, - const std::string &obj_api_named = "", - bool is_obj_api = false) { - auto &code = *code_ptr; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - const auto &field_type = field.value.type; - if (IsStruct(field.value.type)) { - GenerateStructArgs( - *field_type.struct_def, code_ptr, (nameprefix + field.name), - (object_name + "." + field.name), obj_api_named, is_obj_api); - } else { - auto name = Name(field); - auto type = GenType(field.value.type); - if (!is_obj_api) { - code += nameprefix + name + ": " + type; - if (!IsEnum(field.value.type)) { - code += " = "; - auto is_bool = IsBool(field.value.type.base_type); - auto constant = - is_bool ? ("0" == field.value.constant ? "false" : "true") - : field.value.constant; - code += constant; - } - code += ", "; - continue; - } - code += - nameprefix + name + ": " + obj_api_named + object_name + "." + name; - code += ", "; - } - } - } - - // MARK: - Table Generator - - // Generates the reader for swift - void GenTable(const StructDef &struct_def) { - auto is_private_access = struct_def.attributes.Lookup("private"); - code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public"); - - GenObjectHeader(struct_def); - GenTableAccessors(struct_def); - GenTableReader(struct_def); - GenTableWriter(struct_def); - if (parser_.opts.generate_object_based_api) - GenerateObjectAPITableExtension(struct_def); - Outdent(); - code_ += "}\n"; - } - - // Generates the reader for swift - void GenTableAccessors(const StructDef &struct_def) { - // Generate field id constants. - if (struct_def.fields.vec.size() > 0) { - code_ += "private enum {{TABLEOFFSET}}: VOffset {"; - Indent(); - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) { continue; } - code_.SetValue("OFFSET_NAME", Name(field)); - code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset)); - code_ += "case {{OFFSET_NAME}} = {{OFFSET_VALUE}}"; - } - code_ += "var v: Int32 { Int32(self.rawValue) }"; - code_ += "var p: VOffset { self.rawValue }"; - Outdent(); - code_ += "}"; - code_ += ""; - } - } - - void GenObjectHeader(const StructDef &struct_def) { - GenComment(struct_def.doc_comment); - - code_.SetValue("SHORT_STRUCTNAME", Name(struct_def)); - code_.SetValue("STRUCTNAME", NameWrappedInNameSpace(struct_def)); - code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table"); - code_.SetValue("MUTABLE", struct_def.fixed ? Mutable() : ""); - code_ += - "{{ACCESS_TYPE}} struct {{STRUCTNAME}}{{MUTABLE}}: FlatBufferObject\\"; - if (!struct_def.fixed && parser_.opts.generate_object_based_api) - code_ += ", ObjectAPIPacker\\"; - code_ += " {\n"; - Indent(); - code_ += ValidateFunc(); - code_ += - "{{ACCESS_TYPE}} var __buffer: ByteBuffer! { return {{ACCESS}}.bb }"; - code_ += "private var {{ACCESS}}: {{OBJECTTYPE}}\n"; - if (!struct_def.fixed) { - if (parser_.file_identifier_.length()) { - code_.SetValue("FILENAME", parser_.file_identifier_); - code_ += - "{{ACCESS_TYPE}} static func finish(_ fbb: inout " - "FlatBufferBuilder, end: " - "Offset, prefix: Bool = false) { fbb.finish(offset: end, " - "fileId: " - "\"{{FILENAME}}\", addPrefix: prefix) }"; - } - code_ += - "{{ACCESS_TYPE}} static func getRootAs{{SHORT_STRUCTNAME}}(bb: " - "ByteBuffer) -> " - "{{STRUCTNAME}} { return {{STRUCTNAME}}(Table(bb: bb, position: " - "Int32(bb.read(def: UOffset.self, position: bb.reader)) + " - "Int32(bb.reader))) }\n"; - code_ += "private init(_ t: Table) { {{ACCESS}} = t }"; - } - code_ += - "{{ACCESS_TYPE}} init(_ bb: ByteBuffer, o: Int32) { {{ACCESS}} = " - "{{OBJECTTYPE}}(bb: " - "bb, position: o) }"; - code_ += ""; - } - - void GenTableWriter(const StructDef &struct_def) { - flatbuffers::FieldDef *key_field = nullptr; - std::vector<std::string> require_fields; - std::vector<std::string> create_func_body; - std::vector<std::string> create_func_header; - auto should_generate_create = struct_def.fields.vec.size() != 0; - - code_.SetValue("NUMBEROFFIELDS", NumToString(struct_def.fields.vec.size())); - code_ += - "{{ACCESS_TYPE}} static func start{{SHORT_STRUCTNAME}}(_ fbb: inout " - "FlatBufferBuilder) -> " - "UOffset { fbb.startTable(with: {{NUMBEROFFIELDS}}) }"; - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - if (field.key) key_field = &field; - if (field.IsRequired()) - require_fields.push_back(NumToString(field.value.offset)); - - GenTableWriterFields(field, &create_func_body, &create_func_header); - } - code_ += - "{{ACCESS_TYPE}} static func end{{SHORT_STRUCTNAME}}(_ fbb: inout " - "FlatBufferBuilder, " - "start: " - "UOffset) -> Offset { let end = Offset(offset: " - "fbb.endTable(at: start))\\"; - if (require_fields.capacity() != 0) { - std::string fields = ""; - for (auto it = require_fields.begin(); it != require_fields.end(); ++it) - fields += *it + ", "; - code_.SetValue("FIELDS", fields.substr(0, fields.size() - 2)); - code_ += "; fbb.require(table: end, fields: [{{FIELDS}}])\\"; - } - code_ += "; return end }"; - - if (should_generate_create) { - code_ += "{{ACCESS_TYPE}} static func create{{SHORT_STRUCTNAME}}("; - Indent(); - code_ += "_ fbb: inout FlatBufferBuilder,"; - for (auto it = create_func_header.begin(); it < create_func_header.end(); - ++it) { - code_ += *it + "\\"; - if (it < create_func_header.end() - 1) code_ += ","; - } - code_ += ""; - Outdent(); - code_ += ") -> Offset {"; - Indent(); - code_ += "let __start = {{STRUCTNAME}}.start{{SHORT_STRUCTNAME}}(&fbb)"; - for (auto it = create_func_body.begin(); it < create_func_body.end(); - ++it) { - code_ += *it; - } - code_ += - "return {{STRUCTNAME}}.end{{SHORT_STRUCTNAME}}(&fbb, start: __start)"; - Outdent(); - code_ += "}"; - } - - std::string spacing = ""; - - if (key_field != nullptr && !struct_def.fixed && struct_def.has_key) { - code_.SetValue("VALUENAME", NameWrappedInNameSpace(struct_def)); - code_.SetValue("SHORT_VALUENAME", Name(struct_def)); - code_.SetValue("VOFFSET", NumToString(key_field->value.offset)); - - code_ += - "{{ACCESS_TYPE}} static func " - "sortVectorOf{{SHORT_VALUENAME}}(offsets:[Offset], " - "_ fbb: inout FlatBufferBuilder) -> Offset {"; - Indent(); - code_ += spacing + "var off = offsets"; - code_ += - spacing + - "off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: " - "{{VOFFSET}}, fbb: fbb.buffer), Table.offset(Int32($0.o), vOffset: " - "{{VOFFSET}}, fbb: fbb.buffer), fbb: fbb.buffer) < 0 } "; - code_ += spacing + "return fbb.createVector(ofOffsets: off)"; - Outdent(); - code_ += "}"; - GenLookup(*key_field); - } - } - - void GenTableWriterFields(const FieldDef &field, - std::vector<std::string> *create_body, - std::vector<std::string> *create_header) { - std::string builder_string = ", _ fbb: inout FlatBufferBuilder) { "; - auto &create_func_body = *create_body; - auto &create_func_header = *create_header; - auto name = Name(field); - auto type = GenType(field.value.type); - auto opt_scalar = - field.IsOptional() && IsScalar(field.value.type.base_type); - auto nullable_type = opt_scalar ? type + "?" : type; - code_.SetValue("VALUENAME", name); - code_.SetValue("VALUETYPE", nullable_type); - code_.SetValue("OFFSET", name); - code_.SetValue("CONSTANT", field.value.constant); - std::string check_if_vector = - (IsVector(field.value.type) || IsArray(field.value.type)) ? "VectorOf(" - : "("; - auto body = "add" + check_if_vector + name + ": "; - code_ += "{{ACCESS_TYPE}} static func " + body + "\\"; - - create_func_body.push_back("{{STRUCTNAME}}." + body + name + ", &fbb)"); - - if (IsScalar(field.value.type.base_type) && - !IsBool(field.value.type.base_type)) { - std::string is_enum = IsEnum(field.value.type) ? ".rawValue" : ""; - std::string optional_enum = - IsEnum(field.value.type) ? ("?" + is_enum) : ""; - code_ += - "{{VALUETYPE}}" + builder_string + "fbb.add(element: {{VALUENAME}}\\"; - - code_ += field.IsOptional() ? (optional_enum + "\\") - : (is_enum + ", def: {{CONSTANT}}\\"); - - code_ += ", at: {{TABLEOFFSET}}.{{OFFSET}}.p) }"; - - auto default_value = - IsEnum(field.value.type) - ? (field.IsOptional() ? "nil" : GenEnumDefaultValue(field)) - : field.value.constant; - create_func_header.push_back( - "" + name + ": " + nullable_type + " = " + - (field.IsOptional() ? "nil" : default_value)); - return; - } - - if (IsBool(field.value.type.base_type)) { - std::string default_value = - "0" == field.value.constant ? "false" : "true"; - - code_.SetValue("CONSTANT", default_value); - code_.SetValue("VALUETYPE", field.IsOptional() ? "Bool?" : "Bool"); - code_ += "{{VALUETYPE}}" + builder_string + - "fbb.add(element: {{VALUENAME}},\\"; - code_ += field.IsOptional() ? "\\" : " def: {{CONSTANT}},"; - code_ += " at: {{TABLEOFFSET}}.{{OFFSET}}.p) }"; - create_func_header.push_back( - name + ": " + nullable_type + " = " + - (field.IsOptional() ? "nil" : default_value)); - return; - } - - if (IsStruct(field.value.type)) { - auto create_struct = - "guard let {{VALUENAME}} = {{VALUENAME}} else { return };" - " fbb.create(struct: {{VALUENAME}}, position: " - "{{TABLEOFFSET}}.{{OFFSET}}.p) }"; - code_ += type + "?" + builder_string + create_struct; - /// Optional hard coded since structs are always optional - create_func_header.push_back(name + ": " + type + "? = nil"); - return; - } - - auto camel_case_name = - MakeCamel(name, false) + - (IsVector(field.value.type) || IsArray(field.value.type) - ? "VectorOffset" - : "Offset"); - create_func_header.push_back(camel_case_name + " " + name + ": " + - "Offset = Offset()"); - auto reader_type = - IsStruct(field.value.type) && field.value.type.struct_def->fixed - ? "structOffset: {{TABLEOFFSET}}.{{OFFSET}}.p) }" - : "offset: {{VALUENAME}}, at: {{TABLEOFFSET}}.{{OFFSET}}.p) }"; - code_ += "Offset" + builder_string + "fbb.add(" + reader_type; - - auto vectortype = field.value.type.VectorType(); - - if ((vectortype.base_type == BASE_TYPE_STRUCT && - field.value.type.struct_def->fixed) && - (IsVector(field.value.type) || IsArray(field.value.type))) { - auto field_name = NameWrappedInNameSpace(*vectortype.struct_def); - code_ += "public static func startVectorOf" + MakeCamel(name, true) + - "(_ size: Int, in builder: inout " - "FlatBufferBuilder) {"; - Indent(); - code_ += "builder.startVector(size * MemoryLayout<" + field_name + - ">.size, elementSize: MemoryLayout<" + field_name + - ">.alignment)"; - Outdent(); - code_ += "}"; - } - } - - void GenTableReader(const StructDef &struct_def) { - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - GenTableReaderFields(field); - } - } - - void GenTableReaderFields(const FieldDef &field) { - auto offset = NumToString(field.value.offset); - auto name = Name(field); - auto type = GenType(field.value.type); - code_.SetValue("VALUENAME", name); - code_.SetValue("VALUETYPE", type); - code_.SetValue("OFFSET", name); - code_.SetValue("CONSTANT", field.value.constant); - std::string def_Val = field.IsDefault() ? "{{CONSTANT}}" : "nil"; - std::string optional = field.IsOptional() ? "?" : ""; - auto const_string = "return o == 0 ? " + def_Val + " : "; - GenComment(field.doc_comment); - if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type) && - !IsBool(field.value.type.base_type)) { - code_ += GenReaderMainBody(optional) + GenOffset() + const_string + - GenReader("VALUETYPE", "o") + " }"; - if (parser_.opts.mutable_buffer) code_ += GenMutate("o", GenOffset()); - return; - } - - if (IsBool(field.value.type.base_type)) { - std::string default_value = - "0" == field.value.constant ? "false" : "true"; - code_.SetValue("CONSTANT", default_value); - code_.SetValue("VALUETYPE", "Bool"); - code_ += GenReaderMainBody(optional) + "\\"; - code_.SetValue("VALUETYPE", "Byte"); - code_ += GenOffset() + "return o == 0 ? {{CONSTANT}} : 0 != " + - GenReader("VALUETYPE", "o") + " }"; - if (parser_.opts.mutable_buffer) code_ += GenMutate("o", GenOffset()); - return; - } - - if (IsEnum(field.value.type)) { - auto default_value = - field.IsOptional() ? "nil" : GenEnumDefaultValue(field); - code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false)); - code_ += GenReaderMainBody(optional) + "\\"; - code_ += GenOffset() + "return o == 0 ? " + default_value + " : " + - GenEnumConstructor("o") + "?? " + default_value + " }"; - if (parser_.opts.mutable_buffer && !IsUnion(field.value.type)) - code_ += GenMutate("o", GenOffset(), true); - return; - } - - std::string is_required = field.IsRequired() ? "!" : "?"; - auto required_reader = field.IsRequired() ? "return " : const_string; - - if (IsStruct(field.value.type) && field.value.type.struct_def->fixed) { - code_.SetValue("VALUETYPE", GenType(field.value.type)); - code_.SetValue("CONSTANT", "nil"); - code_ += GenReaderMainBody(is_required) + GenOffset() + required_reader + - "{{ACCESS}}.readBuffer(of: {{VALUETYPE}}.self, at: o) }"; - code_.SetValue("VALUENAME", "mutable" + MakeCamel(name)); - code_.SetValue("VALUETYPE", GenType(field.value.type) + Mutable()); - code_.SetValue("CONSTANT", "nil"); - code_ += GenReaderMainBody(is_required) + GenOffset() + required_reader + - GenConstructor("o + {{ACCESS}}.postion"); - return; - } - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: - code_.SetValue("VALUETYPE", GenType(field.value.type)); - code_.SetValue("CONSTANT", "nil"); - code_ += GenReaderMainBody(is_required) + GenOffset() + - required_reader + - GenConstructor(GenIndirect("o + {{ACCESS}}.postion")); - break; - - case BASE_TYPE_STRING: { - auto default_string = "\"" + field.value.constant + "\""; - code_.SetValue("VALUETYPE", GenType(field.value.type)); - code_.SetValue("CONSTANT", field.IsDefault() ? default_string : "nil"); - code_ += GenReaderMainBody(is_required) + GenOffset() + - required_reader + "{{ACCESS}}.string(at: o) }"; - code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}SegmentArray: [UInt8]" + - is_required + - " { return " - "{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) }"; - break; - } - case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru - case BASE_TYPE_VECTOR: GenTableReaderVectorFields(field); break; - case BASE_TYPE_UNION: - code_.SetValue("CONSTANT", "nil"); - code_ += - "{{ACCESS_TYPE}} func {{VALUENAME}}<T: " - "FlatbuffersInitializable>(type: " - "T.Type) -> T" + - is_required + " { " + GenOffset() + required_reader + - "{{ACCESS}}.union(o) }"; - break; - default: FLATBUFFERS_ASSERT(0); - } - } - - void GenTableReaderVectorFields(const FieldDef &field) { - std::string const_string = "return o == 0 ? {{CONSTANT}} : "; - auto vectortype = field.value.type.VectorType(); - code_.SetValue("SIZE", NumToString(InlineSize(vectortype))); - code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}Count: Int32 { " + GenOffset() + - "return o == 0 ? 0 : {{ACCESS}}.vector(count: o) }"; - code_.SetValue("CONSTANT", - IsScalar(vectortype.base_type) == true ? "0" : "nil"); - auto nullable = IsScalar(vectortype.base_type) == true ? "" : "?"; - nullable = IsEnum(vectortype) == true ? "?" : nullable; - - if (vectortype.base_type != BASE_TYPE_UNION) { - code_ += GenArrayMainBody(nullable) + GenOffset() + "\\"; - } else { - code_ += - "{{ACCESS_TYPE}} func {{VALUENAME}}<T: FlatbuffersInitializable>(at " - "index: " - "Int32, type: T.Type) -> T? { " + - GenOffset() + "\\"; - } - - if (IsBool(vectortype.base_type)) { - code_.SetValue("CONSTANT", field.value.offset == 0 ? "false" : "true"); - code_.SetValue("VALUETYPE", "Bool"); - } - - if (!IsEnum(vectortype)) code_ += const_string + "\\"; - - if (IsScalar(vectortype.base_type) && !IsEnum(vectortype) && - !IsBool(field.value.type.base_type)) { - code_ += - "{{ACCESS}}.directRead(of: {{VALUETYPE}}.self, offset: " - "{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }"; - code_ += - "{{ACCESS_TYPE}} var {{VALUENAME}}: [{{VALUETYPE}}] { return " - "{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) ?? [] }"; - if (parser_.opts.mutable_buffer) code_ += GenMutateArray(); - return; - } - - if (vectortype.base_type == BASE_TYPE_STRUCT && - field.value.type.struct_def->fixed) { - code_ += - "{{ACCESS}}.directRead(of: {{VALUETYPE}}.self, offset: " - "{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }"; - code_.SetValue("VALUENAME", "mutable" + MakeCamel(Name(field))); - code_.SetValue("VALUETYPE", GenType(field.value.type) + Mutable()); - code_ += GenArrayMainBody(nullable) + GenOffset() + const_string + - GenConstructor("{{ACCESS}}.vector(at: o) + index * {{SIZE}}"); - - return; - } - - if (IsString(vectortype)) { - code_ += - "{{ACCESS}}.directString(at: {{ACCESS}}.vector(at: o) + " - "index * {{SIZE}}) }"; - return; - } - - if (IsEnum(vectortype)) { - code_.SetValue("BASEVALUE", GenTypeBasic(vectortype, false)); - code_ += "return o == 0 ? {{VALUETYPE}}" + GenEnumDefaultValue(field) + - " : {{VALUETYPE}}(rawValue: {{ACCESS}}.directRead(of: " - "{{BASEVALUE}}.self, offset: {{ACCESS}}.vector(at: o) + " - "index * {{SIZE}})) }"; - return; - } - if (vectortype.base_type == BASE_TYPE_UNION) { - code_ += - "{{ACCESS}}.directUnion({{ACCESS}}.vector(at: o) + " - "index * {{SIZE}}) }"; - return; - } - - if (vectortype.base_type == BASE_TYPE_STRUCT && - !field.value.type.struct_def->fixed) { - code_ += GenConstructor( - "{{ACCESS}}.indirect({{ACCESS}}.vector(at: o) + index * " - "{{SIZE}})"); - auto &sd = *field.value.type.struct_def; - auto &fields = sd.fields.vec; - for (auto kit = fields.begin(); kit != fields.end(); ++kit) { - auto &key_field = **kit; - if (key_field.key) { - GenByKeyFunctions(key_field); - break; - } - } - } - } - - void GenByKeyFunctions(const FieldDef &key_field) { - code_.SetValue("TYPE", GenType(key_field.value.type)); - code_ += - "{{ACCESS_TYPE}} func {{VALUENAME}}By(key: {{TYPE}}) -> {{VALUETYPE}}? " - "{ \\"; - code_ += GenOffset() + - "return o == 0 ? nil : {{VALUETYPE}}.lookupByKey(vector: " - "{{ACCESS}}.vector(at: o), key: key, fbb: {{ACCESS}}.bb) }"; - } - - void GenEnum(const EnumDef &enum_def) { - if (enum_def.generated) return; - auto is_private_access = enum_def.attributes.Lookup("private"); - code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public"); - code_.SetValue("ENUM_NAME", NameWrappedInNameSpace(enum_def)); - code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false)); - GenComment(enum_def.doc_comment); - code_ += "{{ACCESS_TYPE}} enum {{ENUM_NAME}}: {{BASE_TYPE}}, Enum {"; - Indent(); - code_ += "{{ACCESS_TYPE}} typealias T = {{BASE_TYPE}}"; - code_ += - "{{ACCESS_TYPE}} static var byteSize: Int { return " - "MemoryLayout<{{BASE_TYPE}}>.size " - "}"; - code_ += - "{{ACCESS_TYPE}} var value: {{BASE_TYPE}} { return self.rawValue }"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - const auto &ev = **it; - auto name = Name(ev); - code_.SetValue("KEY", name); - code_.SetValue("VALUE", enum_def.ToString(ev)); - GenComment(ev.doc_comment); - code_ += "case {{KEY}} = {{VALUE}}"; - } - code_ += "\n"; - AddMinOrMaxEnumValue(Name(*enum_def.MaxValue()), "max"); - AddMinOrMaxEnumValue(Name(*enum_def.MinValue()), "min"); - Outdent(); - code_ += "}\n"; - if (parser_.opts.generate_object_based_api && enum_def.is_union) { - code_ += "{{ACCESS_TYPE}} struct {{ENUM_NAME}}Union {"; - Indent(); - code_ += "{{ACCESS_TYPE}} var type: {{ENUM_NAME}}"; - code_ += "{{ACCESS_TYPE}} var value: NativeObject?"; - code_ += - "{{ACCESS_TYPE}} init(_ v: NativeObject?, type: {{ENUM_NAME}}) {"; - Indent(); - code_ += "self.type = type"; - code_ += "self.value = v"; - Outdent(); - code_ += "}"; - code_ += - "{{ACCESS_TYPE}} func pack(builder: inout FlatBufferBuilder) -> " - "Offset {"; - Indent(); - BuildUnionEnumSwitchCaseWritter(enum_def); - Outdent(); - code_ += "}"; - Outdent(); - code_ += "}"; - } - } - - // MARK: - Object API - - void GenerateObjectAPIExtensionHeader(std::string name) { - code_ += "\n"; - code_ += "{{ACCESS_TYPE}} mutating func unpack() -> " + name + " {"; - Indent(); - code_ += "return " + name + "(&self)"; - Outdent(); - code_ += "}"; - code_ += - "{{ACCESS_TYPE}} static func pack(_ builder: inout FlatBufferBuilder, " - "obj: " - "inout " + - name + "?) -> Offset {"; - Indent(); - code_ += "guard var obj = obj else { return Offset() }"; - code_ += "return pack(&builder, obj: &obj)"; - Outdent(); - code_ += "}"; - code_ += ""; - code_ += - "{{ACCESS_TYPE}} static func pack(_ builder: inout FlatBufferBuilder, " - "obj: " - "inout " + - name + ") -> Offset {"; - Indent(); - } - - void GenerateObjectAPIStructConstructor(const StructDef &struct_def) { - code_ += - "{{ACCESS_TYPE}} init(_ _t: inout {{STRUCTNAME}}" + Mutable() + ") {"; - Indent(); - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - auto name = Name(field); - auto type = GenType(field.value.type); - code_.SetValue("VALUENAME", name); - if (IsStruct(field.value.type)) { - code_ += "var _v{{VALUENAME}} = _t.{{VALUENAME}}"; - code_ += "_{{VALUENAME}} = _v{{VALUENAME}}.unpack()"; - continue; - } - std::string is_enum = IsEnum(field.value.type) ? ".value" : ""; - code_ += "_{{VALUENAME}} = _t.{{VALUENAME}}" + is_enum; - } - Outdent(); - code_ += "}\n"; - } - - void GenObjectAPI(const StructDef &struct_def) { - code_ += "{{ACCESS_TYPE}} class " + ObjectAPIName("{{STRUCTNAME}}") + - ": NativeObject {\n"; - std::vector<std::string> buffer_constructor; - std::vector<std::string> base_constructor; - Indent(); - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - BuildObjectAPIConstructorBody(field, struct_def.fixed, buffer_constructor, - base_constructor); - } - code_ += ""; - BuildObjectConstructor(buffer_constructor, - "_ _t: inout " + NameWrappedInNameSpace(struct_def)); - BuildObjectConstructor(base_constructor); - if (!struct_def.fixed) - code_ += - "{{ACCESS_TYPE}} func serialize() -> ByteBuffer { return " - "serialize(type: " - "{{STRUCTNAME}}.self) }\n"; - Outdent(); - code_ += "}"; - } - - void GenerateObjectAPITableExtension(const StructDef &struct_def) { - GenerateObjectAPIExtensionHeader(ObjectAPIName("{{STRUCTNAME}}")); - std::vector<std::string> unpack_body; - std::string builder = ", &builder)"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto name = Name(field); - auto type = GenType(field.value.type); - std::string check_if_vector = - (IsVector(field.value.type) || IsArray(field.value.type)) - ? "VectorOf(" - : "("; - std::string body = "add" + check_if_vector + name + ": "; - switch (field.value.type.base_type) { - case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); - case BASE_TYPE_VECTOR: { - GenerateVectorObjectAPITableExtension(field, name, type); - unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + name + - builder); - break; - } - case BASE_TYPE_UNION: { - code_ += "let __" + name + " = obj." + name + - "?.pack(builder: &builder) ?? Offset()"; - unpack_body.push_back("if let o = obj." + name + "?.type {"); - unpack_body.push_back(" {{STRUCTNAME}}.add(" + name + "Type: o" + - builder); - unpack_body.push_back(" {{STRUCTNAME}}." + body + "__" + name + - builder); - unpack_body.push_back("}\n"); - break; - } - case BASE_TYPE_STRUCT: { - if (field.value.type.struct_def && - field.value.type.struct_def->fixed) { - // This is a Struct (IsStruct), not a table. We create - // a native swift object in this case. - std::string code; - GenerateStructArgs(*field.value.type.struct_def, &code, "", "", - "$0", true); - code = code.substr(0, code.size() - 2); - unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." + name + - builder); - } else { - code_ += "let __" + name + " = " + type + - ".pack(&builder, obj: &obj." + name + ")"; - unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + name + - builder); - } - break; - } - case BASE_TYPE_STRING: { - unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + name + - builder); - if (field.IsRequired()) { - code_ += - "let __" + name + " = builder.create(string: obj." + name + ")"; - } else { - BuildingOptionalObjects(name, "builder.create(string: s)"); - } - break; - } - case BASE_TYPE_UTYPE: break; - default: - unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." + name + - builder); - } - } - code_ += "let __root = {{STRUCTNAME}}.start{{SHORT_STRUCTNAME}}(&builder)"; - for (auto it = unpack_body.begin(); it < unpack_body.end(); it++) - code_ += *it; - code_ += - "return {{STRUCTNAME}}.end{{SHORT_STRUCTNAME}}(&builder, start: " - "__root)"; - Outdent(); - code_ += "}"; - } - - void GenerateVectorObjectAPITableExtension(const FieldDef &field, - const std::string &name, - const std::string &type) { - auto vectortype = field.value.type.VectorType(); - switch (vectortype.base_type) { - case BASE_TYPE_UNION: { - code_ += "var __" + name + "__: [Offset] = []"; - code_ += "for i in obj." + name + " {"; - Indent(); - code_ += "guard let off = i?.pack(builder: &builder) else { continue }"; - code_ += "__" + name + "__.append(off)"; - Outdent(); - code_ += "}"; - code_ += "let __" + name + " = builder.createVector(ofOffsets: __" + - name + "__)"; - code_ += "let __" + name + "Type = builder.createVector(obj." + name + - ".compactMap { $0?.type })"; - break; - } - case BASE_TYPE_UTYPE: break; - case BASE_TYPE_STRUCT: { - if (field.value.type.struct_def && - !field.value.type.struct_def->fixed) { - code_ += "var __" + name + "__: [Offset] = []"; - code_ += "for var i in obj." + name + " {"; - Indent(); - code_ += - "__" + name + "__.append(" + type + ".pack(&builder, obj: &i))"; - Outdent(); - code_ += "}"; - code_ += "let __" + name + " = builder.createVector(ofOffsets: __" + - name + "__)"; - } else { - code_ += "{{STRUCTNAME}}.startVectorOf" + MakeCamel(name, true) + - "(obj." + name + ".count, in: &builder)"; - std::string code; - GenerateStructArgs(*field.value.type.struct_def, &code, "", "", "_o", - true); - code = code.substr(0, code.size() - 2); - code_ += "for i in obj." + name + " {"; - Indent(); - code_ += "guard let _o = i else { continue }"; - code_ += "builder.create(struct: _o)"; - Outdent(); - code_ += "}"; - code_ += "let __" + name + " = builder.endVector(len: obj." + name + - ".count)"; - } - break; - } - case BASE_TYPE_STRING: { - code_ += "let __" + name + " = builder.createVector(ofStrings: obj." + - name + ".compactMap({ $0 }) )"; - break; - } - default: { - code_ += "let __" + name + " = builder.createVector(obj." + name + ")"; - break; - } - } - } - - void BuildingOptionalObjects(const std::string &name, - const std::string &body_front) { - code_ += "let __" + name + ": Offset"; - code_ += "if let s = obj." + name + " {"; - Indent(); - code_ += "__" + name + " = " + body_front; - Outdent(); - code_ += "} else {"; - Indent(); - code_ += "__" + name + " = Offset()"; - Outdent(); - code_ += "}"; - code_ += ""; - } - - void BuildObjectConstructor(const std::vector<std::string> &body, - const std::string &header = "") { - code_.SetValue("HEADER", header); - code_ += "{{ACCESS_TYPE}} init({{HEADER}}) {"; - Indent(); - for (auto it = body.begin(); it < body.end(); ++it) code_ += *it; - Outdent(); - code_ += "}\n"; - } - - void BuildObjectAPIConstructorBody( - const FieldDef &field, bool is_fixed, - std::vector<std::string> &buffer_constructor, - std::vector<std::string> &base_constructor) { - auto name = Name(field); - auto type = GenType(field.value.type); - code_.SetValue("VALUENAME", name); - code_.SetValue("VALUETYPE", type); - std::string is_required = field.IsRequired() ? "" : "?"; - - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - type = GenType(field.value.type, true); - code_.SetValue("VALUETYPE", type); - auto optional = - (field.value.type.struct_def && field.value.type.struct_def->fixed); - std::string question_mark = - (field.IsRequired() || (optional && is_fixed) ? "" : "?"); - - code_ += - "{{ACCESS_TYPE}} var {{VALUENAME}}: {{VALUETYPE}}" + question_mark; - base_constructor.push_back("" + name + " = " + type + "()"); - - if (field.value.type.struct_def->fixed) { - buffer_constructor.push_back("" + name + " = _t." + name); - } else { - buffer_constructor.push_back("var __" + name + " = _t." + name); - buffer_constructor.push_back( - "" + name + " = __" + name + - (field.IsRequired() ? "!" : question_mark) + ".unpack()"); - } - break; - } - case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); - case BASE_TYPE_VECTOR: { - BuildObjectAPIConstructorBodyVectors(field, name, buffer_constructor, - base_constructor, " "); - break; - } - case BASE_TYPE_STRING: { - code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: String" + is_required; - buffer_constructor.push_back(name + " = _t." + name); - - if (field.IsRequired()) { - std::string default_value = - field.IsDefault() ? field.value.constant : ""; - base_constructor.push_back(name + " = \"" + default_value + "\""); - break; - } - if (field.IsDefault() && !field.IsRequired()) { - std::string value = field.IsDefault() ? field.value.constant : "nil"; - base_constructor.push_back(name + " = \"" + value + "\""); - } - break; - } - case BASE_TYPE_UTYPE: break; - case BASE_TYPE_UNION: { - BuildUnionEnumSwitchCase(*field.value.type.enum_def, name, - buffer_constructor); - break; - } - default: { - buffer_constructor.push_back(name + " = _t." + name); - std::string nullable = field.IsOptional() ? "?" : ""; - if (IsScalar(field.value.type.base_type) && - !IsBool(field.value.type.base_type) && !IsEnum(field.value.type)) { - code_ += - "{{ACCESS_TYPE}} var {{VALUENAME}}: {{VALUETYPE}}" + nullable; - if (!field.IsOptional()) - base_constructor.push_back(name + " = " + field.value.constant); - break; - } - - if (IsEnum(field.value.type)) { - auto default_value = IsEnum(field.value.type) - ? GenEnumDefaultValue(field) - : field.value.constant; - code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: {{VALUETYPE}}"; - base_constructor.push_back(name + " = " + default_value); - break; - } - - if (IsBool(field.value.type.base_type)) { - code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: Bool" + nullable; - std::string default_value = - "0" == field.value.constant ? "false" : "true"; - if (!field.IsOptional()) - base_constructor.push_back(name + " = " + default_value); - } - } - } - } - - void BuildObjectAPIConstructorBodyVectors( - const FieldDef &field, const std::string &name, - std::vector<std::string> &buffer_constructor, - std::vector<std::string> &base_constructor, - const std::string &indentation) { - auto vectortype = field.value.type.VectorType(); - - if (vectortype.base_type != BASE_TYPE_UTYPE) { - buffer_constructor.push_back(name + " = []"); - buffer_constructor.push_back("for index in 0..<_t." + name + "Count {"); - base_constructor.push_back(name + " = []"); - } - - switch (vectortype.base_type) { - case BASE_TYPE_STRUCT: { - code_.SetValue("VALUETYPE", GenType(vectortype, true)); - code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: [{{VALUETYPE}}?]"; - if (!vectortype.struct_def->fixed) { - buffer_constructor.push_back(indentation + "var __v_ = _t." + name + - "(at: index)"); - buffer_constructor.push_back(indentation + name + - ".append(__v_?.unpack())"); - } else { - buffer_constructor.push_back(indentation + name + ".append(_t." + - name + "(at: index))"); - } - break; - } - case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); - case BASE_TYPE_VECTOR: { - break; - } - case BASE_TYPE_UNION: { - BuildUnionEnumSwitchCase(*field.value.type.enum_def, name, - buffer_constructor, indentation, true); - break; - } - case BASE_TYPE_UTYPE: break; - default: { - code_.SetValue( - "VALUETYPE", - (IsString(vectortype) ? "String?" : GenType(vectortype))); - code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: [{{VALUETYPE}}]"; - - if (IsEnum(vectortype) && vectortype.base_type != BASE_TYPE_UNION) { - auto default_value = IsEnum(field.value.type) - ? GenEnumDefaultValue(field) - : field.value.constant; - buffer_constructor.push_back(indentation + name + ".append(_t." + - name + "(at: index)!)"); - break; - } - buffer_constructor.push_back(indentation + name + ".append(_t." + name + - "(at: index))"); - break; - } - } - if (vectortype.base_type != BASE_TYPE_UTYPE) - buffer_constructor.push_back("}"); - } - - void BuildUnionEnumSwitchCaseWritter(const EnumDef &ev) { - auto field_name = Name(ev); - code_.SetValue("VALUETYPE", field_name); - code_ += "switch type {"; - for (auto it = ev.Vals().begin(); it < ev.Vals().end(); ++it) { - auto field = **it; - auto ev_name = Name(field); - auto type = GenType(field.union_type); - auto is_struct = IsStruct(field.union_type) ? type + Mutable() : type; - if (field.union_type.base_type == BASE_TYPE_NONE) { continue; } - code_ += "case ." + ev_name + ":"; - Indent(); - code_ += "var __obj = value as? " + GenType(field.union_type, true); - code_ += "return " + is_struct + ".pack(&builder, obj: &__obj)"; - Outdent(); - } - code_ += "default: return Offset()"; - code_ += "}"; - } - - void BuildUnionEnumSwitchCase(const EnumDef &ev, const std::string &name, - std::vector<std::string> &buffer_constructor, - const std::string &indentation = "", - const bool is_vector = false) { - auto field_name = NameWrappedInNameSpace(ev); - code_.SetValue("VALUETYPE", field_name); - code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: \\"; - code_ += is_vector ? "[{{VALUETYPE}}Union?]" : "{{VALUETYPE}}Union?"; - - auto vector_reader = is_vector ? "(at: index" : ""; - buffer_constructor.push_back(indentation + "switch _t." + name + "Type" + - vector_reader + (is_vector ? ")" : "") + " {"); - - for (auto it = ev.Vals().begin(); it < ev.Vals().end(); ++it) { - auto field = **it; - auto ev_name = Name(field); - if (field.union_type.base_type == BASE_TYPE_NONE) { continue; } - auto type = IsStruct(field.union_type) - ? GenType(field.union_type) + Mutable() - : GenType(field.union_type); - buffer_constructor.push_back(indentation + "case ." + ev_name + ":"); - buffer_constructor.push_back( - indentation + " var _v = _t." + name + (is_vector ? "" : "(") + - vector_reader + (is_vector ? ", " : "") + "type: " + type + ".self)"); - auto constructor = - field_name + "Union(_v?.unpack(), type: ." + ev_name + ")"; - buffer_constructor.push_back( - indentation + " " + name + - (is_vector ? ".append(" + constructor + ")" : " = " + constructor)); - } - buffer_constructor.push_back(indentation + "default: break"); - buffer_constructor.push_back(indentation + "}"); - } - - void AddMinOrMaxEnumValue(const std::string &str, const std::string &type) { - auto current_value = str; - code_.SetValue(type, current_value); - code_ += "{{ACCESS_TYPE}} static var " + type + - ": {{ENUM_NAME}} { return .{{" + type + "}} }"; - } - - void GenLookup(const FieldDef &key_field) { - code_.SetValue("OFFSET", NumToString(key_field.value.offset)); - std::string offset_reader = - "Table.offset(Int32(fbb.capacity) - tableOffset, vOffset: {{OFFSET}}, " - "fbb: fbb)"; - - code_.SetValue("TYPE", GenType(key_field.value.type)); - code_ += - "fileprivate static func lookupByKey(vector: Int32, key: {{TYPE}}, " - "fbb: " - "ByteBuffer) -> {{VALUENAME}}? {"; - Indent(); - if (IsString(key_field.value.type)) - code_ += "let key = key.utf8.map { $0 }"; - code_ += "var span = fbb.read(def: Int32.self, position: Int(vector - 4))"; - code_ += "var start: Int32 = 0"; - code_ += "while span != 0 {"; - Indent(); - code_ += "var middle = span / 2"; - code_ += - "let tableOffset = Table.indirect(vector + 4 * (start + middle), fbb)"; - if (IsString(key_field.value.type)) { - code_ += "let comp = Table.compare(" + offset_reader + ", key, fbb: fbb)"; - } else { - code_ += "let comp = fbb.read(def: {{TYPE}}.self, position: Int(" + - offset_reader + "))"; - } - - code_ += "if comp > 0 {"; - Indent(); - code_ += "span = middle"; - Outdent(); - code_ += "} else if comp < 0 {"; - Indent(); - code_ += "middle += 1"; - code_ += "start += middle"; - code_ += "span -= middle"; - Outdent(); - code_ += "} else {"; - Indent(); - code_ += "return {{VALUENAME}}(fbb, o: tableOffset)"; - Outdent(); - code_ += "}"; - Outdent(); - code_ += "}"; - code_ += "return nil"; - Outdent(); - code_ += "}"; - } - - inline void GenPadding(const FieldDef &field, int *id) { - if (field.padding) { - for (int i = 0; i < 4; i++) { - if (static_cast<int>(field.padding) & (1 << i)) { - auto bits = (1 << i) * 8; - code_ += "private let padding" + NumToString((*id)++) + "__: UInt" + - NumToString(bits) + " = 0"; - } - } - FLATBUFFERS_ASSERT(!(field.padding & ~0xF)); - } - } - - void GenComment(const std::vector<std::string> &dc) { - if (dc.begin() == dc.end()) { - // Don't output empty comment blocks with 0 lines of comment content. - return; - } - for (auto it = dc.begin(); it != dc.end(); ++it) { code_ += "/// " + *it; } - } - - std::string GenOffset() { - return "let o = {{ACCESS}}.offset({{TABLEOFFSET}}.{{OFFSET}}.v); "; - } - - std::string GenReaderMainBody(const std::string &optional = "") { - return "{{ACCESS_TYPE}} var {{VALUENAME}}: {{VALUETYPE}}" + optional + - " { "; - } - - std::string GenReader(const std::string &type, - const std::string &at = "{{OFFSET}}") { - return "{{ACCESS}}.readBuffer(of: {{" + type + "}}.self, at: " + at + ")"; - } - - std::string GenConstructor(const std::string &offset) { - return "{{VALUETYPE}}({{ACCESS}}.bb, o: " + offset + ") }"; - } - - std::string GenMutate(const std::string &offset, - const std::string &get_offset, bool isRaw = false) { - return "@discardableResult {{ACCESS_TYPE}} func mutate({{VALUENAME}}: " - "{{VALUETYPE}}) -> Bool {" + - get_offset + " return {{ACCESS}}.mutate({{VALUENAME}}" + - (isRaw ? ".rawValue" : "") + ", index: " + offset + ") }"; - } - - std::string GenMutateArray() { - return "{{ACCESS_TYPE}} func mutate({{VALUENAME}}: {{VALUETYPE}}, at " - "index: " - "Int32) -> Bool { " + - GenOffset() + - "return {{ACCESS}}.directMutate({{VALUENAME}}, index: " - "{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }"; - } - - std::string GenEnumDefaultValue(const FieldDef &field) { - auto &value = field.value; - FLATBUFFERS_ASSERT(value.type.enum_def); - auto &enum_def = *value.type.enum_def; - // Vector of enum defaults are always "[]" which never works. - const std::string constant = IsVector(value.type) ? "0" : value.constant; - auto enum_val = enum_def.FindByValue(constant); - std::string name; - if (enum_val) { - name = Name(*enum_val); - } else { - const auto &ev = **enum_def.Vals().begin(); - name = Name(ev); - } - return "." + name; - } - - std::string GenEnumConstructor(const std::string &at) { - return "{{VALUETYPE}}(rawValue: " + GenReader("BASEVALUE", at) + ") "; - } - - std::string ValidateFunc() { - return "static func validateVersion() { FlatBuffersVersion_2_0_0() }"; - } - - std::string GenType(const Type &type, - const bool should_consider_suffix = false) const { - return IsScalar(type.base_type) - ? GenTypeBasic(type) - : (IsArray(type) ? GenType(type.VectorType()) - : GenTypePointer(type, should_consider_suffix)); - } - - std::string GenTypePointer(const Type &type, - const bool should_consider_suffix) const { - switch (type.base_type) { - case BASE_TYPE_STRING: return "String"; - case BASE_TYPE_VECTOR: return GenType(type.VectorType()); - case BASE_TYPE_STRUCT: { - auto &struct_ = *type.struct_def; - if (should_consider_suffix && !struct_.fixed) { - return WrapInNameSpace(struct_.defined_namespace, - ObjectAPIName(Name(struct_))); - } - return WrapInNameSpace(struct_.defined_namespace, Name(struct_)); - } - case BASE_TYPE_UNION: - default: return "FlatbuffersInitializable"; - } - } - - std::string GenTypeBasic(const Type &type) const { - return GenTypeBasic(type, true); - } - - std::string ObjectAPIName(const std::string &name) const { - return parser_.opts.object_prefix + name + parser_.opts.object_suffix; - } - - void Indent() { code_.IncrementIdentLevel(); } - - void Outdent() { code_.DecrementIdentLevel(); } - - std::string NameWrappedInNameSpace(const EnumDef &enum_def) const { - return WrapInNameSpace(enum_def.defined_namespace, Name(enum_def)); - } - - std::string NameWrappedInNameSpace(const StructDef &struct_def) const { - return WrapInNameSpace(struct_def.defined_namespace, Name(struct_def)); - } - - std::string GenTypeBasic(const Type &type, bool can_override) const { - // clang-format off - static const char * const swift_type[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE, STYPE) \ - #STYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on - if (can_override) { - if (type.enum_def) return NameWrappedInNameSpace(*type.enum_def); - if (type.base_type == BASE_TYPE_BOOL) return "Bool"; - } - return swift_type[static_cast<int>(type.base_type)]; - } - - std::string EscapeKeyword(const std::string &name) const { - return keywords_.find(name) == keywords_.end() ? name : name + "_"; - } - - std::string Mutable() const { return "_Mutable"; } - - std::string Name(const EnumVal &ev) const { - auto name = ev.name; - if (isupper(name.front())) { - std::transform(name.begin(), name.end(), name.begin(), CharToLower); - } - return EscapeKeyword(MakeCamel(name, false)); - } - - std::string Name(const Definition &def) const { - return EscapeKeyword(MakeCamel(def.name, false)); - } -}; -} // namespace swift -bool GenerateSwift(const Parser &parser, const std::string &path, - const std::string &file_name) { - swift::SwiftGenerator generator(parser, path, file_name); - return generator.generate(); -} -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_text.cpp b/contrib/libs/flatbuffers/src/idl_gen_text.cpp deleted file mode 100644 index 903c41ecdb..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_text.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients - -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/flexbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -struct PrintScalarTag {}; -struct PrintPointerTag {}; -template<typename T> struct PrintTag { typedef PrintScalarTag type; }; -template<> struct PrintTag<const void *> { typedef PrintPointerTag type; }; - -struct JsonPrinter { - // If indentation is less than 0, that indicates we don't want any newlines - // either. - void AddNewLine() { - if (opts.indent_step >= 0) text += '\n'; - } - - void AddIndent(int ident) { text.append(ident, ' '); } - - int Indent() const { return std::max(opts.indent_step, 0); } - - // Output an identifier with or without quotes depending on strictness. - void OutputIdentifier(const std::string &name) { - if (opts.strict_json) text += '\"'; - text += name; - if (opts.strict_json) text += '\"'; - } - - // Print (and its template specialization below for pointers) generate text - // for a single FlatBuffer value into JSON format. - // The general case for scalars: - template<typename T> - bool PrintScalar(T val, const Type &type, int /*indent*/) { - if (IsBool(type.base_type)) { - text += val != 0 ? "true" : "false"; - return true; // done - } - - if (opts.output_enum_identifiers && type.enum_def) { - const auto &enum_def = *type.enum_def; - if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { - text += '\"'; - text += ev->name; - text += '\"'; - return true; // done - } else if (val && enum_def.attributes.Lookup("bit_flags")) { - const auto entry_len = text.length(); - const auto u64 = static_cast<uint64_t>(val); - uint64_t mask = 0; - text += '\"'; - for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); - it != e; ++it) { - auto f = (*it)->GetAsUInt64(); - if (f & u64) { - mask |= f; - text += (*it)->name; - text += ' '; - } - } - // Don't slice if (u64 != mask) - if (mask && (u64 == mask)) { - text[text.length() - 1] = '\"'; - return true; // done - } - text.resize(entry_len); // restore - } - // print as numeric value - } - - text += NumToString(val); - return true; - } - - void AddComma() { - if (!opts.protobuf_ascii_alike) text += ','; - } - - // Print a vector or an array of JSON values, comma seperated, wrapped in - // "[]". - template<typename Container> - bool PrintContainer(PrintScalarTag, const Container &c, size_t size, - const Type &type, int indent, const uint8_t *) { - const auto elem_indent = indent + Indent(); - text += '['; - AddNewLine(); - for (uoffset_t i = 0; i < size; i++) { - if (i) { - AddComma(); - AddNewLine(); - } - AddIndent(elem_indent); - if (!PrintScalar(c[i], type, elem_indent)) { return false; } - } - AddNewLine(); - AddIndent(indent); - text += ']'; - return true; - } - - // Print a vector or an array of JSON values, comma seperated, wrapped in - // "[]". - template<typename Container> - bool PrintContainer(PrintPointerTag, const Container &c, size_t size, - const Type &type, int indent, const uint8_t *prev_val) { - const auto is_struct = IsStruct(type); - const auto elem_indent = indent + Indent(); - text += '['; - AddNewLine(); - for (uoffset_t i = 0; i < size; i++) { - if (i) { - AddComma(); - AddNewLine(); - } - AddIndent(elem_indent); - auto ptr = is_struct ? reinterpret_cast<const void *>( - c.Data() + type.struct_def->bytesize * i) - : c[i]; - if (!PrintOffset(ptr, type, elem_indent, prev_val, - static_cast<soffset_t>(i))) { - return false; - } - } - AddNewLine(); - AddIndent(indent); - text += ']'; - return true; - } - - template<typename T> - bool PrintVector(const void *val, const Type &type, int indent, - const uint8_t *prev_val) { - typedef Vector<T> Container; - typedef typename PrintTag<typename Container::return_type>::type tag; - auto &vec = *reinterpret_cast<const Container *>(val); - return PrintContainer<Container>(tag(), vec, vec.size(), type, indent, - prev_val); - } - - // Print an array a sequence of JSON values, comma separated, wrapped in "[]". - template<typename T> - bool PrintArray(const void *val, size_t size, const Type &type, int indent) { - typedef Array<T, 0xFFFF> Container; - typedef typename PrintTag<typename Container::return_type>::type tag; - auto &arr = *reinterpret_cast<const Container *>(val); - return PrintContainer<Container>(tag(), arr, size, type, indent, nullptr); - } - - bool PrintOffset(const void *val, const Type &type, int indent, - const uint8_t *prev_val, soffset_t vector_index) { - switch (type.base_type) { - case BASE_TYPE_UNION: { - // If this assert hits, you have an corrupt buffer, a union type field - // was not present or was out of range. - FLATBUFFERS_ASSERT(prev_val); - auto union_type_byte = *prev_val; // Always a uint8_t. - if (vector_index >= 0) { - auto type_vec = reinterpret_cast<const Vector<uint8_t> *>( - prev_val + ReadScalar<uoffset_t>(prev_val)); - union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index)); - } - auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true); - if (enum_val) { - return PrintOffset(val, enum_val->union_type, indent, nullptr, -1); - } else { - return false; - } - } - case BASE_TYPE_STRUCT: - return GenStruct(*type.struct_def, reinterpret_cast<const Table *>(val), - indent); - case BASE_TYPE_STRING: { - auto s = reinterpret_cast<const String *>(val); - return EscapeString(s->c_str(), s->size(), &text, opts.allow_non_utf8, - opts.natural_utf8); - } - case BASE_TYPE_VECTOR: { - const auto vec_type = type.VectorType(); - // Call PrintVector above specifically for each element type: - // clang-format off - switch (vec_type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - if (!PrintVector<CTYPE>( \ - val, vec_type, indent, prev_val)) { \ - return false; \ - } \ - break; - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - } - // clang-format on - return true; - } - case BASE_TYPE_ARRAY: { - const auto vec_type = type.VectorType(); - // Call PrintArray above specifically for each element type: - // clang-format off - switch (vec_type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - if (!PrintArray<CTYPE>( \ - val, type.fixed_length, vec_type, indent)) { \ - return false; \ - } \ - break; - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) - // Arrays of scalars or structs are only possible. - FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0); - } - // clang-format on - return true; - } - default: FLATBUFFERS_ASSERT(0); return false; - } - } - - template<typename T> static T GetFieldDefault(const FieldDef &fd) { - T val; - auto check = StringToNumber(fd.value.constant.c_str(), &val); - (void)check; - FLATBUFFERS_ASSERT(check); - return val; - } - - // Generate text for a scalar field. - template<typename T> - bool GenField(const FieldDef &fd, const Table *table, bool fixed, - int indent) { - return PrintScalar( - fixed ? reinterpret_cast<const Struct *>(table)->GetField<T>( - fd.value.offset) - : table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), - fd.value.type, indent); - } - - // Generate text for non-scalar field. - bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed, - int indent, const uint8_t *prev_val) { - const void *val = nullptr; - if (fixed) { - // The only non-scalar fields in structs are structs or arrays. - FLATBUFFERS_ASSERT(IsStruct(fd.value.type) || IsArray(fd.value.type)); - val = reinterpret_cast<const Struct *>(table)->GetStruct<const void *>( - fd.value.offset); - } else if (fd.flexbuffer) { - auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset); - auto root = flexbuffers::GetRoot(vec->data(), vec->size()); - root.ToString(true, opts.strict_json, text); - return true; - } else if (fd.nested_flatbuffer) { - auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset); - auto root = GetRoot<Table>(vec->data()); - return GenStruct(*fd.nested_flatbuffer, root, indent); - } else { - val = IsStruct(fd.value.type) - ? table->GetStruct<const void *>(fd.value.offset) - : table->GetPointer<const void *>(fd.value.offset); - } - return PrintOffset(val, fd.value.type, indent, prev_val, -1); - } - - // Generate text for a struct or table, values separated by commas, indented, - // and bracketed by "{}" - bool GenStruct(const StructDef &struct_def, const Table *table, int indent) { - text += '{'; - int fieldout = 0; - const uint8_t *prev_val = nullptr; - const auto elem_indent = indent + Indent(); - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - FieldDef &fd = **it; - auto is_present = struct_def.fixed || table->CheckField(fd.value.offset); - auto output_anyway = (opts.output_default_scalars_in_json || fd.key) && - IsScalar(fd.value.type.base_type) && !fd.deprecated; - if (is_present || output_anyway) { - if (fieldout++) { AddComma(); } - AddNewLine(); - AddIndent(elem_indent); - OutputIdentifier(fd.name); - if (!opts.protobuf_ascii_alike || - (fd.value.type.base_type != BASE_TYPE_STRUCT && - fd.value.type.base_type != BASE_TYPE_VECTOR)) - text += ':'; - text += ' '; - // clang-format off - switch (fd.value.type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - if (!GenField<CTYPE>(fd, table, struct_def.fixed, elem_indent)) { \ - return false; \ - } \ - break; - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - // Generate drop-thru case statements for all pointer types: - #define FLATBUFFERS_TD(ENUM, ...) \ - case BASE_TYPE_ ## ENUM: - FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) - FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - if (!GenFieldOffset(fd, table, struct_def.fixed, elem_indent, prev_val)) { - return false; - } - break; - } - // clang-format on - // Track prev val for use with union types. - if (struct_def.fixed) { - prev_val = reinterpret_cast<const uint8_t *>(table) + fd.value.offset; - } else { - prev_val = table->GetAddressOf(fd.value.offset); - } - } - } - AddNewLine(); - AddIndent(indent); - text += '}'; - return true; - } - - JsonPrinter(const Parser &parser, std::string &dest) - : opts(parser.opts), text(dest) { - text.reserve(1024); // Reduce amount of inevitable reallocs. - } - - const IDLOptions &opts; - std::string &text; -}; - -static bool GenerateTextImpl(const Parser &parser, const Table *table, - const StructDef &struct_def, std::string *_text) { - JsonPrinter printer(parser, *_text); - if (!printer.GenStruct(struct_def, table, 0)) { return false; } - printer.AddNewLine(); - return true; -} - -// Generate a text representation of a flatbuffer in JSON format. -bool GenerateTextFromTable(const Parser &parser, const void *table, - const std::string &table_name, std::string *_text) { - auto struct_def = parser.LookupStruct(table_name); - if (struct_def == nullptr) { return false; } - auto root = static_cast<const Table *>(table); - return GenerateTextImpl(parser, root, *struct_def, _text); -} - -// Generate a text representation of a flatbuffer in JSON format. -bool GenerateText(const Parser &parser, const void *flatbuffer, - std::string *_text) { - FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType() - auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer) - : GetRoot<Table>(flatbuffer); - return GenerateTextImpl(parser, root, *parser.root_struct_def_, _text); -} - -static std::string TextFileName(const std::string &path, - const std::string &file_name) { - return path + file_name + ".json"; -} - -bool GenerateTextFile(const Parser &parser, const std::string &path, - const std::string &file_name) { - if (parser.opts.use_flexbuffers) { - std::string json; - parser.flex_root_.ToString(true, parser.opts.strict_json, json); - return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), - json.c_str(), json.size(), true); - } - if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true; - std::string text; - if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &text)) { - return false; - } - return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), text, - false); -} - -std::string TextMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name) { - if (!parser.builder_.GetSize() || !parser.root_struct_def_) return ""; - std::string filebase = - flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); - std::string make_rule = TextFileName(path, filebase) + ": " + file_name; - auto included_files = - parser.GetIncludedFilesRecursive(parser.root_struct_def_->file); - for (auto it = included_files.begin(); it != included_files.end(); ++it) { - make_rule += " " + *it; - } - return make_rule; -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_gen_ts.cpp b/contrib/libs/flatbuffers/src/idl_gen_ts.cpp deleted file mode 100644 index 53e088fe13..0000000000 --- a/contrib/libs/flatbuffers/src/idl_gen_ts.cpp +++ /dev/null @@ -1,1583 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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. - */ - -// independent from idl_parser, since this code is not needed for most clients -#include <algorithm> -#include <cassert> -#include <unordered_map> -#include <unordered_set> - -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -struct ImportDefinition { - std::string name; - std::string statement; - const Definition *dependent; - const Definition *dependency; -}; - -enum AnnotationType { kParam = 0, kType = 1, kReturns = 2 }; - -namespace ts { -// Iterate through all definitions we haven't generate code for (enums, structs, -// and tables) and output them to a single file. -class TsGenerator : public BaseGenerator { - public: - typedef std::map<std::string, ImportDefinition> import_set; - - TsGenerator(const Parser &parser, const std::string &path, - const std::string &file_name) - : BaseGenerator(parser, path, file_name, "", ".", "ts") {} - bool generate() { - generateEnums(); - generateStructs(); - return true; - } - - // Save out the generated code for a single class while adding - // declaration boilerplate. - bool SaveType(const Definition &definition, const std::string &classcode, - import_set &imports, import_set &bare_imports) const { - if (!classcode.length()) return true; - - std::string code = - "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n"; - - for (auto it = bare_imports.begin(); it != bare_imports.end(); it++) - code += it->second.statement + "\n"; - if (!bare_imports.empty()) code += "\n"; - - for (auto it = imports.begin(); it != imports.end(); it++) - if (it->second.dependency != &definition) // do not import itself - code += it->second.statement + "\n"; - if (!imports.empty()) code += "\n\n"; - - code += classcode; - auto filename = NamespaceDir(*definition.defined_namespace, true) + - ToDasherizedCase(definition.name) + ".ts"; - return SaveFile(filename.c_str(), code, false); - } - - private: - // Generate code for all enums. - void generateEnums() { - for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); - ++it) { - import_set bare_imports; - import_set imports; - std::string enumcode; - auto &enum_def = **it; - GenEnum(enum_def, &enumcode, imports, false); - GenEnum(enum_def, &enumcode, imports, true); - SaveType(enum_def, enumcode, imports, bare_imports); - } - } - - // Generate code for all structs. - void generateStructs() { - for (auto it = parser_.structs_.vec.begin(); - it != parser_.structs_.vec.end(); ++it) { - import_set bare_imports; - import_set imports; - AddImport(bare_imports, "* as flatbuffers", "flatbuffers"); - auto &struct_def = **it; - std::string declcode; - GenStruct(parser_, struct_def, &declcode, imports); - SaveType(struct_def, declcode, imports, bare_imports); - } - } - - // Generate a documentation comment, if available. - static void GenDocComment(const std::vector<std::string> &dc, - std::string *code_ptr, - const char *indent = nullptr) { - if (dc.empty()) { - // Don't output empty comment blocks with 0 lines of comment content. - return; - } - - std::string &code = *code_ptr; - if (indent) code += indent; - code += "/**\n"; - for (auto it = dc.begin(); it != dc.end(); ++it) { - if (indent) code += indent; - code += " *" + *it + "\n"; - } - if (indent) code += indent; - code += " */\n"; - } - - static void GenDocComment(std::string *code_ptr) { - GenDocComment(std::vector<std::string>(), code_ptr); - } - - // Generate an enum declaration and an enum string lookup table. - void GenEnum(EnumDef &enum_def, std::string *code_ptr, import_set &imports, - bool reverse) { - if (enum_def.generated) return; - if (reverse) return; // FIXME. - std::string &code = *code_ptr; - GenDocComment(enum_def.doc_comment, code_ptr); - std::string ns = GetNameSpace(enum_def); - std::string enum_def_name = enum_def.name + (reverse ? "Name" : ""); - code += "export enum " + enum_def.name + "{\n"; - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { - auto &ev = **it; - if (!ev.doc_comment.empty()) { - if (it != enum_def.Vals().begin()) { code += '\n'; } - GenDocComment(ev.doc_comment, code_ptr, " "); - } - - // Generate mapping between EnumName: EnumValue(int) - if (reverse) { - code += " '" + enum_def.ToString(ev) + "'"; - code += " = "; - code += "'" + ev.name + "'"; - } else { - code += " " + ev.name; - code += " = "; - code += enum_def.ToString(ev); - } - - code += (it + 1) != enum_def.Vals().end() ? ",\n" : "\n"; - } - code += "}"; - - if (enum_def.is_union) { - code += GenUnionConvFunc(enum_def.underlying_type, imports); - } - - code += "\n\n"; - } - - static std::string GenType(const Type &type) { - switch (type.base_type) { - case BASE_TYPE_BOOL: - case BASE_TYPE_CHAR: return "Int8"; - case BASE_TYPE_UTYPE: - case BASE_TYPE_UCHAR: return "Uint8"; - case BASE_TYPE_SHORT: return "Int16"; - case BASE_TYPE_USHORT: return "Uint16"; - case BASE_TYPE_INT: return "Int32"; - case BASE_TYPE_UINT: return "Uint32"; - case BASE_TYPE_LONG: return "Int64"; - case BASE_TYPE_ULONG: return "Uint64"; - case BASE_TYPE_FLOAT: return "Float32"; - case BASE_TYPE_DOUBLE: return "Float64"; - case BASE_TYPE_STRING: return "String"; - case BASE_TYPE_VECTOR: return GenType(type.VectorType()); - case BASE_TYPE_STRUCT: return type.struct_def->name; - default: return "flatbuffers.Table"; - } - } - - std::string GenGetter(const Type &type, const std::string &arguments) { - switch (type.base_type) { - case BASE_TYPE_STRING: return GenBBAccess() + ".__string" + arguments; - case BASE_TYPE_STRUCT: return GenBBAccess() + ".__struct" + arguments; - case BASE_TYPE_UNION: - if (!UnionHasStringType(*type.enum_def)) { - return GenBBAccess() + ".__union" + arguments; - } - return GenBBAccess() + ".__union_with_string" + arguments; - case BASE_TYPE_VECTOR: return GenGetter(type.VectorType(), arguments); - default: { - auto getter = - GenBBAccess() + ".read" + MakeCamel(GenType(type)) + arguments; - if (type.base_type == BASE_TYPE_BOOL) { getter = "!!" + getter; } - return getter; - } - } - } - - std::string GenBBAccess() const { return "this.bb!"; } - - std::string GenDefaultValue(const FieldDef &field, const std::string &context, - import_set &imports) { - if (field.IsScalarOptional()) { return "null"; } - - const auto &value = field.value; - if (value.type.enum_def && value.type.base_type != BASE_TYPE_UNION && - value.type.base_type != BASE_TYPE_VECTOR) { - if (auto val = value.type.enum_def->FindByValue(value.constant)) { - return AddImport(imports, *value.type.enum_def, *value.type.enum_def) + - "." + val->name; - } else { - return value.constant; - } - } - - switch (value.type.base_type) { - case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true"; - - case BASE_TYPE_STRING: - case BASE_TYPE_UNION: - case BASE_TYPE_STRUCT: { - return "null"; - } - - case BASE_TYPE_VECTOR: return "[]"; - - case BASE_TYPE_LONG: - case BASE_TYPE_ULONG: { - int64_t constant = StringToInt(value.constant.c_str()); - std::string createLong = context + ".createLong"; - return createLong + "(" + NumToString(static_cast<int32_t>(constant)) + - ", " + NumToString(static_cast<int32_t>(constant >> 32)) + ")"; - } - - default: return value.constant; - } - } - - std::string GenTypeName(import_set &imports, const Definition &owner, - const Type &type, bool input, - bool allowNull = false) { - if (!input) { - if (IsString(type) || type.base_type == BASE_TYPE_STRUCT) { - std::string name; - if (IsString(type)) { - name = "string|Uint8Array"; - } else { - name = AddImport(imports, owner, *type.struct_def); - } - return allowNull ? (name + "|null") : name; - } - } - - switch (type.base_type) { - case BASE_TYPE_BOOL: return allowNull ? "boolean|null" : "boolean"; - case BASE_TYPE_LONG: - case BASE_TYPE_ULONG: - return allowNull ? "flatbuffers.Long|null" : "flatbuffers.Long"; - default: - if (IsScalar(type.base_type)) { - if (type.enum_def) { - const auto enum_name = AddImport(imports, owner, *type.enum_def); - return allowNull ? (enum_name + "|null") : enum_name; - } - return allowNull ? "number|null" : "number"; - } - return "flatbuffers.Offset"; - } - } - - // Returns the method name for use with add/put calls. - static std::string GenWriteMethod(const Type &type) { - // Forward to signed versions since unsigned versions don't exist - switch (type.base_type) { - case BASE_TYPE_UTYPE: - case BASE_TYPE_UCHAR: return GenWriteMethod(Type(BASE_TYPE_CHAR)); - case BASE_TYPE_USHORT: return GenWriteMethod(Type(BASE_TYPE_SHORT)); - case BASE_TYPE_UINT: return GenWriteMethod(Type(BASE_TYPE_INT)); - case BASE_TYPE_ULONG: return GenWriteMethod(Type(BASE_TYPE_LONG)); - default: break; - } - - return IsScalar(type.base_type) ? MakeCamel(GenType(type)) - : (IsStruct(type) ? "Struct" : "Offset"); - } - - template<typename T> static std::string MaybeAdd(T value) { - return value != 0 ? " + " + NumToString(value) : ""; - } - - template<typename T> static std::string MaybeScale(T value) { - return value != 1 ? " * " + NumToString(value) : ""; - } - - void GenStructArgs(import_set &imports, const StructDef &struct_def, - std::string *arguments, const std::string &nameprefix) { - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (IsStruct(field.value.type)) { - // Generate arguments for a struct inside a struct. To ensure names - // don't clash, and to make it obvious these arguments are constructing - // a nested struct, prefix the name with the field name. - GenStructArgs(imports, *field.value.type.struct_def, arguments, - nameprefix + field.name + "_"); - } else { - *arguments += - ", " + nameprefix + field.name + ": " + - GenTypeName(imports, field, field.value.type, true, field.IsOptional()); - } - } - } - - static void GenStructBody(const StructDef &struct_def, std::string *body, - const std::string &nameprefix) { - *body += " builder.prep("; - *body += NumToString(struct_def.minalign) + ", "; - *body += NumToString(struct_def.bytesize) + ");\n"; - - for (auto it = struct_def.fields.vec.rbegin(); - it != struct_def.fields.vec.rend(); ++it) { - auto &field = **it; - if (field.padding) { - *body += " builder.pad(" + NumToString(field.padding) + ");\n"; - } - if (IsStruct(field.value.type)) { - // Generate arguments for a struct inside a struct. To ensure names - // don't clash, and to make it obvious these arguments are constructing - // a nested struct, prefix the name with the field name. - GenStructBody(*field.value.type.struct_def, body, - nameprefix + field.name + "_"); - } else { - *body += " builder.write" + GenWriteMethod(field.value.type) + "("; - if (field.value.type.base_type == BASE_TYPE_BOOL) { *body += "+"; } - *body += nameprefix + field.name + ");\n"; - } - } - } - - std::string GenerateNewExpression(const std::string &object_name) { - return "new " + object_name + "()"; - } - - void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr, - std::string &code, const std::string &object_name, - bool size_prefixed) { - if (!struct_def.fixed) { - GenDocComment(code_ptr); - std::string sizePrefixed("SizePrefixed"); - code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" + - GetPrefixedName(struct_def, "As"); - code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name + - "):" + object_name + " {\n"; - if (size_prefixed) { - code += - " bb.setPosition(bb.position() + " - "flatbuffers.SIZE_PREFIX_LENGTH);\n"; - } - code += " return (obj || " + GenerateNewExpression(object_name); - code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n"; - code += "}\n\n"; - } - } - - void GenerateFinisher(StructDef &struct_def, std::string *code_ptr, - std::string &code, bool size_prefixed) { - if (parser_.root_struct_def_ == &struct_def) { - std::string sizePrefixed("SizePrefixed"); - GenDocComment(code_ptr); - - code += "static finish" + (size_prefixed ? sizePrefixed : "") + - GetPrefixedName(struct_def) + "Buffer"; - code += "(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n"; - code += " builder.finish(offset"; - if (!parser_.file_identifier_.empty()) { - code += ", '" + parser_.file_identifier_ + "'"; - } - if (size_prefixed) { - if (parser_.file_identifier_.empty()) { code += ", undefined"; } - code += ", true"; - } - code += ");\n"; - code += "}\n\n"; - } - } - - static std::string GetObjApiClassName(const StructDef &sd, - const IDLOptions &opts) { - return GetObjApiClassName(sd.name, opts); - } - - static std::string GetObjApiClassName(const std::string &name, - const IDLOptions &opts) { - return opts.object_prefix + name + opts.object_suffix; - } - - bool UnionHasStringType(const EnumDef &union_enum) { - return std::any_of(union_enum.Vals().begin(), union_enum.Vals().end(), - [](const EnumVal *ev) { - return !ev->IsZero() && IsString(ev->union_type); - }); - } - - std::string GenUnionGenericTypeTS(const EnumDef &union_enum) { - // TODO: make it work without any - // return std::string("T") + (UnionHasStringType(union_enum) ? "|string" : - // ""); - return std::string("any") + - (UnionHasStringType(union_enum) ? "|string" : ""); - } - - std::string GenUnionTypeTS(const EnumDef &union_enum, import_set &imports) { - std::string ret; - std::set<std::string> type_list; - - for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end(); - ++it) { - const auto &ev = **it; - if (ev.IsZero()) { continue; } - - std::string type = ""; - if (IsString(ev.union_type)) { - type = "string"; // no need to wrap string type in namespace - } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) { - type = AddImport(imports, union_enum, *ev.union_type.struct_def); - } else { - FLATBUFFERS_ASSERT(false); - } - type_list.insert(type); - } - - for (auto it = type_list.begin(); it != type_list.end(); ++it) { - ret += *it + ((std::next(it) == type_list.end()) ? "" : "|"); - } - - return ret; - } - - std::string AddImport(import_set &imports, const Definition &dependent, - const StructDef &dependency) { - std::string ns; - const auto &depc_comps = dependency.defined_namespace->components; - for (auto it = depc_comps.begin(); it != depc_comps.end(); it++) ns += *it; - std::string unique_name = ns + dependency.name; - std::string import_name = dependency.name; - std::string long_import_name; - if (imports.find(unique_name) != imports.end()) - return imports.find(unique_name)->second.name; - for (auto it = imports.begin(); it != imports.end(); it++) { - if (it->second.name == import_name) { - long_import_name = ns + import_name; - break; - } - } - std::string import_statement; - import_statement += "import { "; - if (long_import_name.empty()) { - import_statement += import_name; - if (parser_.opts.generate_object_based_api) - import_statement += ", " + import_name + "T"; - } else { - import_statement += dependency.name + " as " + long_import_name; - if (parser_.opts.generate_object_based_api) - import_statement += - ", " + dependency.name + "T as " + long_import_name + "T"; - } - import_statement += " } from '"; - std::string file_name; - const auto &dep_comps = dependent.defined_namespace->components; - for (size_t i = 0; i < dep_comps.size(); i++) - file_name += i == 0 ? ".." : (kPathSeparator + std::string("..")); - if (dep_comps.size() == 0) file_name += "."; - for (auto it = depc_comps.begin(); it != depc_comps.end(); it++) - file_name += kPathSeparator + ToDasherizedCase(*it); - file_name += kPathSeparator + ToDasherizedCase(dependency.name); - import_statement += file_name + "';"; - ImportDefinition import; - import.name = long_import_name.empty() ? import_name : long_import_name; - import.statement = import_statement; - import.dependency = &dependency; - import.dependent = &dependent; - imports.insert(std::make_pair(unique_name, import)); - return import.name; - } - - // TODO: largely (but not identical) duplicated code from above couln't find a - // good way to refactor - std::string AddImport(import_set &imports, const Definition &dependent, - const EnumDef &dependency) { - std::string ns; - const auto &depc_comps = dependency.defined_namespace->components; - for (auto it = depc_comps.begin(); it != depc_comps.end(); it++) ns += *it; - std::string unique_name = ns + dependency.name; - std::string import_name = dependency.name; - std::string long_import_name; - if (imports.find(unique_name) != imports.end()) - return imports.find(unique_name)->second.name; - for (auto it = imports.begin(); it != imports.end(); it++) { - if (it->second.name == import_name) { - long_import_name = ns + import_name; - break; - } - } - std::string import_statement; - import_statement += "import { "; - if (long_import_name.empty()) - import_statement += import_name; - else - import_statement += dependency.name + " as " + long_import_name; - if (dependency.is_union) { - import_statement += ", unionTo" + import_name; - import_statement += ", unionListTo" + import_name; - } - import_statement += " } from '"; - std::string file_name; - const auto &dep_comps = dependent.defined_namespace->components; - for (size_t i = 0; i < dep_comps.size(); i++) - file_name += i == 0 ? ".." : (kPathSeparator + std::string("..")); - if (dep_comps.size() == 0) file_name += "."; - for (auto it = depc_comps.begin(); it != depc_comps.end(); it++) - file_name += kPathSeparator + ToDasherizedCase(*it); - file_name += kPathSeparator + ToDasherizedCase(dependency.name); - import_statement += file_name + "';"; - ImportDefinition import; - import.name = long_import_name.empty() ? import_name : long_import_name; - import.statement = import_statement; - import.dependency = &dependency; - import.dependent = &dependent; - imports.insert(std::make_pair(unique_name, import)); - return import.name; - } - - void AddImport(import_set &imports, std::string import_name, - std::string fileName) { - ImportDefinition import; - import.name = import_name; - import.statement = "import " + import_name + " from '" + fileName + "';"; - imports.insert(std::make_pair(import_name, import)); - } - - // Generate a TS union type based on a union's enum - std::string GenObjApiUnionTypeTS(import_set &imports, const IDLOptions &opts, - const EnumDef &union_enum) { - std::string ret = ""; - std::set<std::string> type_list; - - for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end(); - ++it) { - const auto &ev = **it; - if (ev.IsZero()) { continue; } - - std::string type = ""; - if (IsString(ev.union_type)) { - type = "string"; // no need to wrap string type in namespace - } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) { - type = GetObjApiClassName( - AddImport(imports, union_enum, *ev.union_type.struct_def), opts); - } else { - FLATBUFFERS_ASSERT(false); - } - type_list.insert(type); - } - - size_t totalPrinted = 0; - for (auto it = type_list.begin(); it != type_list.end(); ++it) { - ++totalPrinted; - ret += *it + ((totalPrinted == type_list.size()) ? "" : "|"); - } - - return ret; - } - - std::string GenUnionConvFuncName(const EnumDef &enum_def) { - return "unionTo" + enum_def.name; - } - - std::string GenUnionListConvFuncName(const EnumDef &enum_def) { - return "unionListTo" + enum_def.name; - } - - std::string GenUnionConvFunc(const Type &union_type, import_set &imports) { - if (union_type.enum_def) { - const auto &enum_def = *union_type.enum_def; - - const auto valid_union_type = GenUnionTypeTS(enum_def, imports); - const auto valid_union_type_with_null = valid_union_type + "|null"; - - auto ret = "\n\nexport function " + GenUnionConvFuncName(enum_def) + - "(\n type: " + enum_def.name + - ",\n accessor: (obj:" + valid_union_type + ") => " + - valid_union_type_with_null + - "\n): " + valid_union_type_with_null + " {\n"; - - const auto enum_type = AddImport(imports, enum_def, enum_def); - - const auto union_enum_loop = [&](const std::string &accessor_str) { - ret += " switch(" + enum_type + "[type]) {\n"; - ret += " case 'NONE': return null; \n"; - - for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); - ++it) { - const auto &ev = **it; - if (ev.IsZero()) { continue; } - - ret += " case '" + ev.name + "': "; - - if (IsString(ev.union_type)) { - ret += "return " + accessor_str + "'') as string;"; - } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) { - const auto type = - AddImport(imports, enum_def, *ev.union_type.struct_def); - ret += "return " + accessor_str + "new " + type + "())! as " + - type + ";"; - } else { - FLATBUFFERS_ASSERT(false); - } - ret += "\n"; - } - - ret += " default: return null;\n"; - ret += " }\n"; - }; - - union_enum_loop("accessor("); - ret += "}"; - - ret += "\n\nexport function " + GenUnionListConvFuncName(enum_def) + - "(\n type: " + enum_def.name + - ", \n accessor: (index: number, obj:" + valid_union_type + - ") => " + valid_union_type_with_null + - ", \n index: number\n): " + valid_union_type_with_null + " {\n"; - union_enum_loop("accessor(index, "); - ret += "}"; - - return ret; - } - FLATBUFFERS_ASSERT(0); - return ""; - } - - // Used for generating a short function that returns the correct class - // based on union enum type. Assume the context is inside the non object api - // type - std::string GenUnionValTS(import_set &imports, const std::string &field_name, - const Type &union_type, - const bool is_array = false) { - if (union_type.enum_def) { - const auto &enum_def = *union_type.enum_def; - const auto enum_type = AddImport(imports, enum_def, enum_def); - const std::string union_accessor = "this." + field_name; - - const auto union_has_string = UnionHasStringType(enum_def); - const auto field_binded_method = "this." + field_name + ".bind(this)"; - - std::string ret; - - if (!is_array) { - const auto conversion_function = GenUnionConvFuncName(enum_def); - const auto target_enum = "this." + field_name + "Type()"; - - ret = "(() => {\n"; - ret += " let temp = " + conversion_function + "(" + target_enum + - ", " + field_binded_method + ");\n"; - ret += " if(temp === null) { return null; }\n"; - ret += union_has_string - ? " if(typeof temp === 'string') { return temp; }\n" - : ""; - ret += " return temp.unpack()\n"; - ret += " })()"; - } else { - const auto conversion_function = GenUnionListConvFuncName(enum_def); - const auto target_enum_accesor = "this." + field_name + "Type"; - const auto target_enum_length = target_enum_accesor + "Length()"; - - ret = "(() => {\n"; - ret += " let ret = [];\n"; - ret += " for(let targetEnumIndex = 0; targetEnumIndex < " + - target_enum_length + - "; " - "++targetEnumIndex) {\n"; - ret += " let targetEnum = " + target_enum_accesor + - "(targetEnumIndex);\n"; - ret += " if(targetEnum === null || " + enum_type + - "[targetEnum!] === 'NONE') { " - "continue; }\n\n"; - ret += " let temp = " + conversion_function + "(targetEnum, " + - field_binded_method + ", targetEnumIndex);\n"; - ret += " if(temp === null) { continue; }\n"; - ret += union_has_string ? " if(typeof temp === 'string') { " - "ret.push(temp); continue; }\n" - : ""; - ret += " ret.push(temp.unpack());\n"; - ret += " }\n"; - ret += " return ret;\n"; - ret += " })()"; - } - - return ret; - } - - FLATBUFFERS_ASSERT(0); - return ""; - } - - static std::string GenNullCheckConditional( - const std::string &nullCheckVar, const std::string &trueVal, - const std::string &falseVal = "null") { - return "(" + nullCheckVar + " !== null ? " + trueVal + " : " + falseVal + - ")"; - } - - std::string GenStructMemberValueTS(const StructDef &struct_def, - const std::string &prefix, - const std::string &delimiter, - const bool nullCheck = true) { - std::string ret; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - - const auto curr_member_accessor = - prefix + "." + MakeCamel(field.name, false); - if (IsStruct(field.value.type)) { - ret += GenStructMemberValueTS(*field.value.type.struct_def, - curr_member_accessor, delimiter); - } else { - if (nullCheck) { - ret += - "(" + prefix + " === null ? 0 : " + curr_member_accessor + "!)"; - } else { - ret += curr_member_accessor; - } - } - - if (std::next(it) != struct_def.fields.vec.end()) { ret += delimiter; } - } - - return ret; - } - - void GenObjApi(const Parser &parser, StructDef &struct_def, - std::string &obj_api_unpack_func, std::string &obj_api_class, - import_set &imports) { - const auto class_name = GetObjApiClassName(struct_def, parser.opts); - - std::string unpack_func = "\nunpack(): " + class_name + - " {\n return new " + class_name + "(" + - (struct_def.fields.vec.empty() ? "" : "\n"); - std::string unpack_to_func = "\nunpackTo(_o: " + class_name + "): void {" + - +(struct_def.fields.vec.empty() ? "" : "\n"); - - std::string constructor_func = "constructor("; - constructor_func += (struct_def.fields.vec.empty() ? "" : "\n"); - - const auto has_create = - struct_def.fixed || CanCreateFactoryMethod(struct_def); - - std::string pack_func_prototype = - "\npack(builder:flatbuffers.Builder): flatbuffers.Offset {\n"; - - std::string pack_func_offset_decl; - std::string pack_func_create_call; - - const auto struct_name = AddImport(imports, struct_def, struct_def); - - if (has_create) { - pack_func_create_call = " return " + struct_name + ".create" + - GetPrefixedName(struct_def) + "(builder" + - (struct_def.fields.vec.empty() ? "" : ",\n "); - } else { - pack_func_create_call = " " + struct_name + ".start" + - GetPrefixedName(struct_def) + "(builder);\n"; - } - - if (struct_def.fixed) { - // when packing struct, nested struct's members instead of the struct's - // offset are used - pack_func_create_call += - GenStructMemberValueTS(struct_def, "this", ",\n ", false) + "\n "; - } - - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - - const auto field_name = MakeCamel(field.name, false); - const std::string field_binded_method = - "this." + field_name + ".bind(this)"; - - std::string field_val; - std::string field_type; - // a string that declares a variable containing the - // offset for things that can't be generated inline - // empty otw - std::string field_offset_decl; - // 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, "flatbuffers", imports); - - // Emit a scalar field - const auto is_string = IsString(field.value.type); - if (IsScalar(field.value.type.base_type) || is_string) { - const auto has_null_default = is_string || HasNullDefault(field); - - field_type += GenTypeName(imports, field, field.value.type, false, - has_null_default); - field_val = "this." + field_name + "()"; - - if (field.value.type.base_type != BASE_TYPE_STRING) { - field_offset_val = "this." + field_name; - } else { - field_offset_decl = GenNullCheckConditional( - "this." + field_name, - "builder.createString(this." + field_name + "!)", "0"); - } - } - - // Emit an object field - else { - auto is_vector = false; - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - const auto &sd = *field.value.type.struct_def; - field_type += GetObjApiClassName(sd, parser.opts); - - const std::string field_accessor = "this." + field_name + "()"; - field_val = GenNullCheckConditional(field_accessor, - field_accessor + "!.unpack()"); - auto packing = GenNullCheckConditional( - "this." + field_name, "this." + field_name + "!.pack(builder)", - "0"); - - if (sd.fixed) { - field_offset_val = std::move(packing); - } else { - field_offset_decl = std::move(packing); - } - - break; - } - - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - auto vectortypename = - GenTypeName(imports, struct_def, vectortype, false); - is_vector = true; - - field_type = "("; - - switch (vectortype.base_type) { - case BASE_TYPE_STRUCT: { - const auto &sd = *field.value.type.struct_def; - field_type += GetObjApiClassName(sd, parser.opts); - field_type += ")[]"; - - field_val = GenBBAccess() + ".createObjList(" + - field_binded_method + ", this." + field_name + - "Length())"; - - if (sd.fixed) { - field_offset_decl = - "builder.createStructOffsetList(this." + field_name + - ", " + AddImport(imports, struct_def, struct_def) + - ".start" + MakeCamel(field_name) + "Vector)"; - } else { - field_offset_decl = - AddImport(imports, struct_def, struct_def) + ".create" + - MakeCamel(field_name) + - "Vector(builder, builder.createObjectOffsetList(" + - "this." + field_name + "))"; - } - - break; - } - - case BASE_TYPE_STRING: { - field_type += "string)[]"; - field_val = GenBBAccess() + ".createScalarList(" + - field_binded_method + ", this." + field_name + - "Length())"; - field_offset_decl = - AddImport(imports, struct_def, struct_def) + ".create" + - MakeCamel(field_name) + - "Vector(builder, builder.createObjectOffsetList(" + - "this." + field_name + "))"; - break; - } - - case BASE_TYPE_UNION: { - field_type += GenObjApiUnionTypeTS(imports, parser.opts, - *(vectortype.enum_def)); - field_type += ")[]"; - field_val = - GenUnionValTS(imports, field_name, vectortype, true); - - field_offset_decl = - AddImport(imports, struct_def, struct_def) + ".create" + - MakeCamel(field_name) + - "Vector(builder, builder.createObjectOffsetList(" + - "this." + field_name + "))"; - - break; - } - default: { - if (vectortype.enum_def) { - field_type += GenTypeName(imports, struct_def, vectortype, - false, HasNullDefault(field)); - } else { - field_type += vectortypename; - } - field_type += ")[]"; - field_val = GenBBAccess() + ".createScalarList(" + - field_binded_method + ", this." + field_name + - "Length())"; - - field_offset_decl = AddImport(imports, struct_def, struct_def) + - ".create" + MakeCamel(field_name) + - "Vector(builder, this." + field_name + ")"; - - break; - } - } - - break; - } - - case BASE_TYPE_UNION: { - field_type += GenObjApiUnionTypeTS(imports, parser.opts, - *(field.value.type.enum_def)); - - field_val = GenUnionValTS(imports, field_name, field.value.type); - field_offset_decl = - "builder.createObjectOffset(this." + field_name + ")"; - break; - } - - default: FLATBUFFERS_ASSERT(0); break; - } - - // length 0 vector is simply empty instead of null - field_type += is_vector ? "" : "|null"; - } - - if (!field_offset_decl.empty()) { - field_offset_decl = - " const " + field_name + " = " + field_offset_decl + ";"; - } - if (field_offset_val.empty()) { field_offset_val = field_name; } - - unpack_func += " " + field_val; - unpack_to_func += " _o." + field_name + " = " + field_val + ";"; - - constructor_func += " public " + field_name + ": " + field_type + " = " + - field_default_val; - - if (!struct_def.fixed) { - if (!field_offset_decl.empty()) { - pack_func_offset_decl += field_offset_decl + "\n"; - } - - if (has_create) { - pack_func_create_call += field_offset_val; - } else { - pack_func_create_call += " " + struct_name + ".add" + - MakeCamel(field.name) + "(builder, " + - field_offset_val + ");\n"; - } - } - - if (std::next(it) != struct_def.fields.vec.end()) { - constructor_func += ",\n"; - - if (!struct_def.fixed && has_create) { - pack_func_create_call += ",\n "; - } - - unpack_func += ",\n"; - unpack_to_func += "\n"; - } else { - constructor_func += "\n"; - if (!struct_def.fixed) { - pack_func_offset_decl += (pack_func_offset_decl.empty() ? "" : "\n"); - pack_func_create_call += "\n "; - } - - unpack_func += "\n "; - unpack_to_func += "\n"; - } - } - - constructor_func += "){}\n\n"; - - if (has_create) { - pack_func_create_call += ");"; - } else { - pack_func_create_call += "return " + struct_name + ".end" + - GetPrefixedName(struct_def) + "(builder);"; - } - - obj_api_class = "\nexport class " + - GetObjApiClassName(struct_def, parser.opts) + " {\n"; - - obj_api_class += constructor_func; - obj_api_class += pack_func_prototype + pack_func_offset_decl + - pack_func_create_call + "\n}"; - - obj_api_class += "\n}\n"; - - unpack_func += ");\n}"; - unpack_to_func += "}\n"; - - obj_api_unpack_func = unpack_func + "\n\n" + unpack_to_func; - } - - static bool CanCreateFactoryMethod(const StructDef &struct_def) { - // to preserve backwards compatibility, we allow the first field to be a - // struct - return struct_def.fields.vec.size() < 2 || - std::all_of(std::begin(struct_def.fields.vec) + 1, - std::end(struct_def.fields.vec), - [](const FieldDef *f) -> bool { - FLATBUFFERS_ASSERT(f != nullptr); - return f->value.type.base_type != BASE_TYPE_STRUCT; - }); - } - - // Generate an accessor struct with constructor for a flatbuffers struct. - void GenStruct(const Parser &parser, StructDef &struct_def, - std::string *code_ptr, import_set &imports) { - if (struct_def.generated) return; - std::string &code = *code_ptr; - - std::string object_name; - std::string object_namespace = GetNameSpace(struct_def); - - // Emit constructor - object_name = struct_def.name; - GenDocComment(struct_def.doc_comment, code_ptr); - code += "export class " + struct_def.name; - code += " {\n"; - code += " bb: flatbuffers.ByteBuffer|null = null;\n"; - code += " bb_pos = 0;\n"; - - // Generate the __init method that sets the field in a pre-existing - // accessor object. This is to allow object reuse. - code += - "__init(i:number, bb:flatbuffers.ByteBuffer):" + object_name + " {\n"; - code += " this.bb_pos = i;\n"; - code += " this.bb = bb;\n"; - code += " return this;\n"; - code += "}\n\n"; - - // Generate special accessors for the table that when used as the root of a - // FlatBuffer - GenerateRootAccessor(struct_def, code_ptr, code, object_name, false); - GenerateRootAccessor(struct_def, code_ptr, code, object_name, true); - - // Generate the identifier check method - if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def && - !parser_.file_identifier_.empty()) { - GenDocComment(code_ptr); - code += - "static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean " - "{\n"; - code += " return bb.__has_identifier('" + parser_.file_identifier_; - code += "');\n}\n\n"; - } - - // Emit field accessors - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - auto offset_prefix = - " const offset = " + GenBBAccess() + ".__offset(this.bb_pos, " + - NumToString(field.value.offset) + ");\n return offset ? "; - - // Emit a scalar field - const auto is_string = IsString(field.value.type); - if (IsScalar(field.value.type.base_type) || is_string) { - const auto has_null_default = is_string || HasNullDefault(field); - - GenDocComment(field.doc_comment, code_ptr); - std::string prefix = MakeCamel(field.name, false) + "("; - if (is_string) { - code += prefix + "):string|null\n"; - code += - prefix + "optionalEncoding:flatbuffers.Encoding" + "):" + - GenTypeName(imports, struct_def, field.value.type, false, true) + - "\n"; - code += prefix + "optionalEncoding?:any"; - } else { - code += prefix; - } - if (field.value.type.enum_def) { - code += "):" + - GenTypeName(imports, struct_def, field.value.type, false, - field.IsOptional()) + - " {\n"; - } else { - code += "):" + - GenTypeName(imports, struct_def, field.value.type, false, - has_null_default) + - " {\n"; - } - - if (struct_def.fixed) { - code += - " return " + - GenGetter(field.value.type, - "(this.bb_pos" + MaybeAdd(field.value.offset) + ")") + - ";\n"; - } else { - std::string index = "this.bb_pos + offset"; - if (is_string) { index += ", optionalEncoding"; } - code += offset_prefix + - GenGetter(field.value.type, "(" + index + ")") + " : " + - GenDefaultValue(field, GenBBAccess(), imports); - code += ";\n"; - } - } - - // Emit an object field - else { - switch (field.value.type.base_type) { - case BASE_TYPE_STRUCT: { - const auto type = - AddImport(imports, struct_def, *field.value.type.struct_def); - GenDocComment(field.doc_comment, code_ptr); - code += MakeCamel(field.name, false); - code += "(obj?:" + type + "):" + type + "|null {\n"; - - if (struct_def.fixed) { - code += " return (obj || " + GenerateNewExpression(type); - code += ").__init(this.bb_pos"; - code += - MaybeAdd(field.value.offset) + ", " + GenBBAccess() + ");\n"; - } else { - code += offset_prefix + "(obj || " + GenerateNewExpression(type) + - ").__init("; - code += field.value.type.struct_def->fixed - ? "this.bb_pos + offset" - : GenBBAccess() + ".__indirect(this.bb_pos + offset)"; - code += ", " + GenBBAccess() + ") : null;\n"; - } - - break; - } - - case BASE_TYPE_VECTOR: { - auto vectortype = field.value.type.VectorType(); - auto vectortypename = - GenTypeName(imports, struct_def, vectortype, false); - auto inline_size = InlineSize(vectortype); - auto index = GenBBAccess() + - ".__vector(this.bb_pos + offset) + index" + - MaybeScale(inline_size); - std::string ret_type; - bool is_union = false; - switch (vectortype.base_type) { - case BASE_TYPE_STRUCT: ret_type = vectortypename; break; - case BASE_TYPE_STRING: ret_type = vectortypename; break; - case BASE_TYPE_UNION: - ret_type = "?flatbuffers.Table"; - is_union = true; - break; - default: ret_type = vectortypename; - } - GenDocComment(field.doc_comment, code_ptr); - std::string prefix = MakeCamel(field.name, false); - // TODO: make it work without any - // if (is_union) { prefix += "<T extends flatbuffers.Table>"; } - if (is_union) { prefix += ""; } - prefix += "(index: number"; - if (is_union) { - const auto union_type = - GenUnionGenericTypeTS(*(field.value.type.enum_def)); - - vectortypename = union_type; - code += prefix + ", obj:" + union_type; - } else if (vectortype.base_type == BASE_TYPE_STRUCT) { - code += prefix + ", obj?:" + vectortypename; - } else if (IsString(vectortype)) { - code += prefix + "):string\n"; - code += prefix + ",optionalEncoding:flatbuffers.Encoding" + - "):" + vectortypename + "\n"; - code += prefix + ",optionalEncoding?:any"; - } else { - code += prefix; - } - code += "):" + vectortypename + "|null {\n"; - - if (vectortype.base_type == BASE_TYPE_STRUCT) { - code += offset_prefix + "(obj || " + - GenerateNewExpression(vectortypename); - code += ").__init("; - code += vectortype.struct_def->fixed - ? index - : GenBBAccess() + ".__indirect(" + index + ")"; - code += ", " + GenBBAccess() + ")"; - } else { - if (is_union) { - index = "obj, " + index; - } else if (IsString(vectortype)) { - index += ", optionalEncoding"; - } - code += offset_prefix + GenGetter(vectortype, "(" + index + ")"); - } - code += " : "; - if (field.value.type.element == BASE_TYPE_BOOL) { - code += "false"; - } else if (field.value.type.element == BASE_TYPE_LONG || - field.value.type.element == BASE_TYPE_ULONG) { - code += GenBBAccess() + ".createLong(0, 0)"; - } else if (IsScalar(field.value.type.element)) { - if (field.value.type.enum_def) { - code += field.value.constant; - } else { - code += "0"; - } - } else { - code += "null"; - } - code += ";\n"; - break; - } - - case BASE_TYPE_UNION: { - GenDocComment(field.doc_comment, code_ptr); - code += MakeCamel(field.name, false); - - const auto &union_enum = *(field.value.type.enum_def); - const auto union_type = GenUnionGenericTypeTS(union_enum); - code += "<T extends flatbuffers.Table>(obj:" + union_type + - "):" + union_type + - "|null " - "{\n"; - - code += offset_prefix + - GenGetter(field.value.type, "(obj, this.bb_pos + offset)") + - " : null;\n"; - break; - } - default: FLATBUFFERS_ASSERT(0); - } - } - code += "}\n\n"; - - // Adds the mutable scalar value to the output - if (IsScalar(field.value.type.base_type) && parser.opts.mutable_buffer && - !IsUnion(field.value.type)) { - std::string type = - GenTypeName(imports, struct_def, field.value.type, true); - - code += "mutate_" + field.name + "(value:" + type + "):boolean {\n"; - - if (struct_def.fixed) { - code += " " + GenBBAccess() + ".write" + - MakeCamel(GenType(field.value.type)) + "(this.bb_pos + " + - NumToString(field.value.offset) + ", "; - } else { - code += " const offset = " + GenBBAccess() + - ".__offset(this.bb_pos, " + NumToString(field.value.offset) + - ");\n\n"; - code += " if (offset === 0) {\n"; - code += " return false;\n"; - code += " }\n\n"; - - // special case for bools, which are treated as uint8 - code += " " + GenBBAccess() + ".write" + - MakeCamel(GenType(field.value.type)) + - "(this.bb_pos + offset, "; - if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; } - } - - code += "value);\n"; - code += " return true;\n"; - code += "}\n\n"; - } - - // Emit vector helpers - if (IsVector(field.value.type)) { - // Emit a length helper - GenDocComment(code_ptr); - code += MakeCamel(field.name, false); - code += "Length():number {\n" + offset_prefix; - - code += - GenBBAccess() + ".__vector_len(this.bb_pos + offset) : 0;\n}\n\n"; - - // For scalar types, emit a typed array helper - auto vectorType = field.value.type.VectorType(); - if (IsScalar(vectorType.base_type) && !IsLong(vectorType.base_type)) { - GenDocComment(code_ptr); - - code += MakeCamel(field.name, false); - code += "Array():" + GenType(vectorType) + "Array|null {\n" + - offset_prefix; - - code += "new " + GenType(vectorType) + "Array(" + GenBBAccess() + - ".bytes().buffer, " + GenBBAccess() + - ".bytes().byteOffset + " + GenBBAccess() + - ".__vector(this.bb_pos + offset), " + GenBBAccess() + - ".__vector_len(this.bb_pos + offset)) : null;\n}\n\n"; - } - } - } - - // Emit the fully qualified name - if (parser_.opts.generate_name_strings) { - GenDocComment(code_ptr); - code += "static getFullyQualifiedName():string {\n"; - code += " return '" + WrapInNameSpace(struct_def) + "';\n"; - code += "}\n\n"; - } - - // Emit the size of the struct. - if (struct_def.fixed) { - GenDocComment(code_ptr); - code += "static sizeOf():number {\n"; - code += " return " + NumToString(struct_def.bytesize) + ";\n"; - code += "}\n\n"; - } - - // Emit a factory constructor - if (struct_def.fixed) { - std::string arguments; - GenStructArgs(imports, struct_def, &arguments, ""); - GenDocComment(code_ptr); - - code += "static create" + GetPrefixedName(struct_def) + - "(builder:flatbuffers.Builder"; - code += arguments + "):flatbuffers.Offset {\n"; - - GenStructBody(struct_def, &code, ""); - code += " return builder.offset();\n}\n\n"; - } else { - // Generate a method to start building a new object - GenDocComment(code_ptr); - - code += "static start" + GetPrefixedName(struct_def) + - "(builder:flatbuffers.Builder) {\n"; - - code += " builder.startObject(" + - NumToString(struct_def.fields.vec.size()) + ");\n"; - code += "}\n\n"; - - // Generate a set of static methods that allow table construction - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (field.deprecated) continue; - const auto argname = GetArgName(field); - - // Generate the field insertion method - GenDocComment(code_ptr); - code += "static add" + MakeCamel(field.name); - code += "(builder:flatbuffers.Builder, " + argname + ":" + - GetArgType(imports, struct_def, field, false) + ") {\n"; - code += " builder.addField" + GenWriteMethod(field.value.type) + "("; - code += NumToString(it - struct_def.fields.vec.begin()) + ", "; - if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; } - code += argname + ", "; - if (!IsScalar(field.value.type.base_type)) { - code += "0"; - } else if (HasNullDefault(field)) { - if (IsLong(field.value.type.base_type)) { - code += "builder.createLong(0, 0)"; - } else { - code += "0"; - } - } else { - if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; } - code += GenDefaultValue(field, "builder", imports); - } - code += ");\n}\n\n"; - - if (IsVector(field.value.type)) { - auto vector_type = field.value.type.VectorType(); - auto alignment = InlineAlignment(vector_type); - auto elem_size = InlineSize(vector_type); - - // Generate a method to create a vector from a JavaScript array - if (!IsStruct(vector_type)) { - GenDocComment(code_ptr); - - const std::string sig_begin = - "static create" + MakeCamel(field.name) + - "Vector(builder:flatbuffers.Builder, data:"; - const std::string sig_end = "):flatbuffers.Offset"; - std::string type = - GenTypeName(imports, struct_def, vector_type, true) + "[]"; - if (type == "number[]") { - const auto &array_type = GenType(vector_type); - // the old type should be deprecated in the future - std::string type_old = "number[]|Uint8Array"; - std::string type_new = "number[]|" + array_type + "Array"; - if (type_old == type_new) { - type = type_new; - } else { - // add function overloads - code += sig_begin + type_new + sig_end + ";\n"; - code += - "/**\n * @deprecated This Uint8Array overload will " - "be removed in the future.\n */\n"; - code += sig_begin + type_old + sig_end + ";\n"; - type = type_new + "|Uint8Array"; - } - } - code += sig_begin + type + sig_end + " {\n"; - code += " builder.startVector(" + NumToString(elem_size); - code += ", data.length, " + NumToString(alignment) + ");\n"; - code += " for (let i = data.length - 1; i >= 0; i--) {\n"; - code += " builder.add" + GenWriteMethod(vector_type) + "("; - if (vector_type.base_type == BASE_TYPE_BOOL) { code += "+"; } - code += "data[i]!);\n"; - code += " }\n"; - code += " return builder.endVector();\n"; - code += "}\n\n"; - } - - // Generate a method to start a vector, data to be added manually - // after - GenDocComment(code_ptr); - - code += "static start" + MakeCamel(field.name); - code += "Vector(builder:flatbuffers.Builder, numElems:number) {\n"; - code += " builder.startVector(" + NumToString(elem_size); - code += ", numElems, " + NumToString(alignment) + ");\n"; - code += "}\n\n"; - } - } - - // Generate a method to stop building a new object - GenDocComment(code_ptr); - - code += "static end" + GetPrefixedName(struct_def); - code += "(builder:flatbuffers.Builder):flatbuffers.Offset {\n"; - - code += " const offset = builder.endObject();\n"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - auto &field = **it; - if (!field.deprecated && field.IsRequired()) { - code += " builder.requiredField(offset, "; - code += NumToString(field.value.offset); - code += ") // " + field.name + "\n"; - } - } - code += " return offset;\n"; - code += "}\n\n"; - - // Generate the methods to complete buffer construction - GenerateFinisher(struct_def, code_ptr, code, false); - GenerateFinisher(struct_def, code_ptr, code, true); - - // Generate a convenient CreateX function - if (CanCreateFactoryMethod(struct_def)) { - code += "static create" + GetPrefixedName(struct_def); - code += "(builder:flatbuffers.Builder"; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) continue; - code += ", " + GetArgName(field) + ":" + - GetArgType(imports, struct_def, field, true); - } - - code += "):flatbuffers.Offset {\n"; - code += " " + struct_def.name + ".start" + - GetPrefixedName(struct_def) + "(builder);\n"; - - std::string methodPrefix = struct_def.name; - for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { - const auto &field = **it; - if (field.deprecated) continue; - - const auto arg_name = GetArgName(field); - - if (field.IsScalarOptional()) { - code += " if (" + arg_name + " !== null)\n "; - } - - code += " " + methodPrefix + ".add" + MakeCamel(field.name) + "("; - code += "builder, " + arg_name + ");\n"; - } - - code += " return " + methodPrefix + ".end" + - GetPrefixedName(struct_def) + "(builder);\n"; - code += "}\n"; - } - } - - if (!struct_def.fixed && parser_.services_.vec.size() != 0) { - auto name = GetPrefixedName(struct_def, ""); - code += "\n"; - code += "serialize():Uint8Array {\n"; - code += " return this.bb!.bytes();\n"; - code += "}\n"; - - code += "\n"; - code += "static deserialize(buffer: Uint8Array):" + name + " {\n"; - code += " return " + AddImport(imports, struct_def, struct_def) + - ".getRootAs" + name + "(new flatbuffers.ByteBuffer(buffer))\n"; - code += "}\n"; - } - - if (parser_.opts.generate_object_based_api) { - std::string obj_api_class; - std::string obj_api_unpack_func; - GenObjApi(parser_, struct_def, obj_api_unpack_func, obj_api_class, - imports); - - code += obj_api_unpack_func + "}\n" + obj_api_class; - } else { - code += "}\n"; - } - } - - static bool HasNullDefault(const FieldDef &field) { - return field.IsOptional() && field.value.constant == "null"; - } - - std::string GetArgType(import_set &imports, const Definition &owner, - const FieldDef &field, bool allowNull) { - return GenTypeName(imports, owner, field.value.type, true, - allowNull && field.IsOptional()); - } - - static std::string GetArgName(const FieldDef &field) { - auto argname = MakeCamel(field.name, false); - if (!IsScalar(field.value.type.base_type)) { argname += "Offset"; } - - return argname; - } - - std::string GetPrefixedName(const StructDef &struct_def, - const char *prefix = "") { - return prefix + struct_def.name; - } -}; // namespace ts -} // namespace ts - -bool GenerateTS(const Parser &parser, const std::string &path, - const std::string &file_name) { - ts::TsGenerator generator(parser, path, file_name); - return generator.generate(); -} - -std::string TSMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name) { - FLATBUFFERS_ASSERT(parser.opts.lang <= IDLOptions::kMAX); - - std::string filebase = - flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); - ts::TsGenerator generator(parser, path, file_name); - std::string make_rule = - generator.GeneratedFileName(path, filebase, parser.opts) + ": "; - - auto included_files = parser.GetIncludedFilesRecursive(file_name); - for (auto it = included_files.begin(); it != included_files.end(); ++it) { - make_rule += " " + *it; - } - return make_rule; -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/idl_parser.cpp b/contrib/libs/flatbuffers/src/idl_parser.cpp deleted file mode 100644 index ad642d79a9..0000000000 --- a/contrib/libs/flatbuffers/src/idl_parser.cpp +++ /dev/null @@ -1,3986 +0,0 @@ -/* - * Copyright 2014 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 - * - * 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 <algorithm> -#include <cmath> -#include <list> -#include <string> -#include <utility> - -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -// Reflects the version at the compiling time of binary(lib/dll/so). -const char *FLATBUFFERS_VERSION() { - // clang-format off - return - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "." - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "." - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION); - // clang-format on -} - -const double kPi = 3.14159265358979323846; - -// clang-format off -const char *const kTypeNames[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \ - IDLTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - nullptr -}; - -const char kTypeSizes[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - sizeof(CTYPE), - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD -}; -// clang-format on - -// The enums in the reflection schema should match the ones we use internally. -// Compare the last element to check if these go out of sync. -static_assert(BASE_TYPE_UNION == static_cast<BaseType>(reflection::Union), - "enums don't match"); - -// Any parsing calls have to be wrapped in this macro, which automates -// handling of recursive error checking a bit. It will check the received -// CheckedError object, and return straight away on error. -#define ECHECK(call) \ - { \ - auto ce = (call); \ - if (ce.Check()) return ce; \ - } - -// These two functions are called hundreds of times below, so define a short -// form: -#define NEXT() ECHECK(Next()) -#define EXPECT(tok) ECHECK(Expect(tok)) - -static bool ValidateUTF8(const std::string &str) { - const char *s = &str[0]; - const char *const sEnd = s + str.length(); - while (s < sEnd) { - if (FromUTF8(&s) < 0) { return false; } - } - return true; -} - -static bool IsLowerSnakeCase(const std::string &str) { - for (size_t i = 0; i < str.length(); i++) { - char c = str[i]; - if (!check_ascii_range(c, 'a', 'z') && !is_digit(c) && c != '_') { - return false; - } - } - return true; -} - -// Convert an underscore_based_identifier in to camelCase. -// Also uppercases the first character if first is true. -std::string MakeCamel(const std::string &in, bool first) { - std::string s; - for (size_t i = 0; i < in.length(); i++) { - if (!i && first) - s += CharToUpper(in[0]); - else if (in[i] == '_' && i + 1 < in.length()) - s += CharToUpper(in[++i]); - else - s += in[i]; - } - return s; -} - -// Convert an underscore_based_identifier in to screaming snake case. -std::string MakeScreamingCamel(const std::string &in) { - std::string s; - for (size_t i = 0; i < in.length(); i++) { - if (in[i] != '_') - s += CharToUpper(in[i]); - else - s += in[i]; - } - return s; -} - -void DeserializeDoc(std::vector<std::string> &doc, - const Vector<Offset<String>> *documentation) { - if (documentation == nullptr) return; - for (uoffset_t index = 0; index < documentation->size(); index++) - doc.push_back(documentation->Get(index)->str()); -} - -void Parser::Message(const std::string &msg) { - if (!error_.empty()) error_ += "\n"; // log all warnings and errors - error_ += file_being_parsed_.length() ? AbsolutePath(file_being_parsed_) : ""; - // clang-format off - - #ifdef _WIN32 // MSVC alike - error_ += - "(" + NumToString(line_) + ", " + NumToString(CursorPosition()) + ")"; - #else // gcc alike - if (file_being_parsed_.length()) error_ += ":"; - error_ += NumToString(line_) + ": " + NumToString(CursorPosition()); - #endif - // clang-format on - error_ += ": " + msg; -} - -void Parser::Warning(const std::string &msg) { - if (!opts.no_warnings) Message("warning: " + msg); -} - -CheckedError Parser::Error(const std::string &msg) { - Message("error: " + msg); - return CheckedError(true); -} - -inline CheckedError NoError() { return CheckedError(false); } - -CheckedError Parser::RecurseError() { - return Error("maximum parsing depth " + NumToString(parse_depth_counter_) + - " reached"); -} - -class Parser::ParseDepthGuard { - public: - explicit ParseDepthGuard(Parser *parser_not_null) - : parser_(*parser_not_null), caller_depth_(parser_.parse_depth_counter_) { - FLATBUFFERS_ASSERT(caller_depth_ <= (FLATBUFFERS_MAX_PARSING_DEPTH) && - "Check() must be called to prevent stack overflow"); - parser_.parse_depth_counter_ += 1; - } - - ~ParseDepthGuard() { parser_.parse_depth_counter_ -= 1; } - - CheckedError Check() { - return caller_depth_ >= (FLATBUFFERS_MAX_PARSING_DEPTH) - ? parser_.RecurseError() - : CheckedError(false); - } - - FLATBUFFERS_DELETE_FUNC(ParseDepthGuard(const ParseDepthGuard &)); - FLATBUFFERS_DELETE_FUNC(ParseDepthGuard &operator=(const ParseDepthGuard &)); - - private: - Parser &parser_; - const int caller_depth_; -}; - -template<typename T> std::string TypeToIntervalString() { - return "[" + NumToString((flatbuffers::numeric_limits<T>::lowest)()) + "; " + - NumToString((flatbuffers::numeric_limits<T>::max)()) + "]"; -} - -// atot: template version of atoi/atof: convert a string to an instance of T. -template<typename T> -bool atot_scalar(const char *s, T *val, bool_constant<false>) { - return StringToNumber(s, val); -} - -template<typename T> -bool atot_scalar(const char *s, T *val, bool_constant<true>) { - // Normalize NaN parsed from fbs or json to unsigned NaN. - if (false == StringToNumber(s, val)) return false; - *val = (*val != *val) ? std::fabs(*val) : *val; - return true; -} - -template<typename T> CheckedError atot(const char *s, Parser &parser, T *val) { - auto done = atot_scalar(s, val, bool_constant<is_floating_point<T>::value>()); - if (done) return NoError(); - if (0 == *val) - return parser.Error("invalid number: \"" + std::string(s) + "\""); - else - return parser.Error("invalid number: \"" + std::string(s) + "\"" + - ", constant does not fit " + TypeToIntervalString<T>()); -} -template<> -inline CheckedError atot<Offset<void>>(const char *s, Parser &parser, - Offset<void> *val) { - (void)parser; - *val = Offset<void>(atoi(s)); - return NoError(); -} - -std::string Namespace::GetFullyQualifiedName(const std::string &name, - size_t max_components) const { - // Early exit if we don't have a defined namespace. - if (components.empty() || !max_components) { return name; } - std::string stream_str; - for (size_t i = 0; i < std::min(components.size(), max_components); i++) { - stream_str += components[i]; - stream_str += '.'; - } - if (!stream_str.empty()) stream_str.pop_back(); - if (name.length()) { - stream_str += '.'; - stream_str += name; - } - return stream_str; -} - -template<typename T> -T *LookupTableByName(const SymbolTable<T> &table, const std::string &name, - const Namespace ¤t_namespace, size_t skip_top) { - const auto &components = current_namespace.components; - if (table.dict.empty()) return nullptr; - if (components.size() < skip_top) return nullptr; - const auto N = components.size() - skip_top; - std::string full_name; - for (size_t i = 0; i < N; i++) { - full_name += components[i]; - full_name += '.'; - } - for (size_t i = N; i > 0; i--) { - full_name += name; - auto obj = table.Lookup(full_name); - if (obj) return obj; - auto len = full_name.size() - components[i - 1].size() - 1 - name.size(); - full_name.resize(len); - } - FLATBUFFERS_ASSERT(full_name.empty()); - return table.Lookup(name); // lookup in global namespace -} - -// Declare tokens we'll use. Single character tokens are represented by their -// ascii character code (e.g. '{'), others above 256. -// clang-format off -#define FLATBUFFERS_GEN_TOKENS(TD) \ - TD(Eof, 256, "end of file") \ - TD(StringConstant, 257, "string constant") \ - TD(IntegerConstant, 258, "integer constant") \ - TD(FloatConstant, 259, "float constant") \ - TD(Identifier, 260, "identifier") -#ifdef __GNUC__ -__extension__ // Stop GCC complaining about trailing comma with -Wpendantic. -#endif -enum { - #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) kToken ## NAME = VALUE, - FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN) - #undef FLATBUFFERS_TOKEN -}; - -static std::string TokenToString(int t) { - static const char * const tokens[] = { - #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) STRING, - FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN) - #undef FLATBUFFERS_TOKEN - #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \ - IDLTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - if (t < 256) { // A single ascii char token. - std::string s; - s.append(1, static_cast<char>(t)); - return s; - } else { // Other tokens. - return tokens[t - 256]; - } -} -// clang-format on - -std::string Parser::TokenToStringId(int t) const { - return t == kTokenIdentifier ? attribute_ : TokenToString(t); -} - -// Parses exactly nibbles worth of hex digits into a number, or error. -CheckedError Parser::ParseHexNum(int nibbles, uint64_t *val) { - FLATBUFFERS_ASSERT(nibbles > 0); - for (int i = 0; i < nibbles; i++) - if (!is_xdigit(cursor_[i])) - return Error("escape code must be followed by " + NumToString(nibbles) + - " hex digits"); - std::string target(cursor_, cursor_ + nibbles); - *val = StringToUInt(target.c_str(), 16); - cursor_ += nibbles; - return NoError(); -} - -CheckedError Parser::SkipByteOrderMark() { - if (static_cast<unsigned char>(*cursor_) != 0xef) return NoError(); - cursor_++; - if (static_cast<unsigned char>(*cursor_) != 0xbb) - return Error("invalid utf-8 byte order mark"); - cursor_++; - if (static_cast<unsigned char>(*cursor_) != 0xbf) - return Error("invalid utf-8 byte order mark"); - cursor_++; - return NoError(); -} - -static inline bool IsIdentifierStart(char c) { - return is_alpha(c) || (c == '_'); -} - -CheckedError Parser::Next() { - doc_comment_.clear(); - bool seen_newline = cursor_ == source_; - attribute_.clear(); - attr_is_trivial_ascii_string_ = true; - for (;;) { - char c = *cursor_++; - token_ = c; - switch (c) { - case '\0': - cursor_--; - token_ = kTokenEof; - return NoError(); - case ' ': - case '\r': - case '\t': break; - case '\n': - MarkNewLine(); - seen_newline = true; - break; - case '{': - case '}': - case '(': - case ')': - case '[': - case ']': - case ',': - case ':': - case ';': - case '=': return NoError(); - case '\"': - case '\'': { - int unicode_high_surrogate = -1; - - while (*cursor_ != c) { - if (*cursor_ < ' ' && static_cast<signed char>(*cursor_) >= 0) - return Error("illegal character in string constant"); - if (*cursor_ == '\\') { - attr_is_trivial_ascii_string_ = false; // has escape sequence - cursor_++; - if (unicode_high_surrogate != -1 && *cursor_ != 'u') { - return Error( - "illegal Unicode sequence (unpaired high surrogate)"); - } - switch (*cursor_) { - case 'n': - attribute_ += '\n'; - cursor_++; - break; - case 't': - attribute_ += '\t'; - cursor_++; - break; - case 'r': - attribute_ += '\r'; - cursor_++; - break; - case 'b': - attribute_ += '\b'; - cursor_++; - break; - case 'f': - attribute_ += '\f'; - cursor_++; - break; - case '\"': - attribute_ += '\"'; - cursor_++; - break; - case '\'': - attribute_ += '\''; - cursor_++; - break; - case '\\': - attribute_ += '\\'; - cursor_++; - break; - case '/': - attribute_ += '/'; - cursor_++; - break; - case 'x': { // Not in the JSON standard - cursor_++; - uint64_t val; - ECHECK(ParseHexNum(2, &val)); - attribute_ += static_cast<char>(val); - break; - } - case 'u': { - cursor_++; - uint64_t val; - ECHECK(ParseHexNum(4, &val)); - if (val >= 0xD800 && val <= 0xDBFF) { - if (unicode_high_surrogate != -1) { - return Error( - "illegal Unicode sequence (multiple high surrogates)"); - } else { - unicode_high_surrogate = static_cast<int>(val); - } - } else if (val >= 0xDC00 && val <= 0xDFFF) { - if (unicode_high_surrogate == -1) { - return Error( - "illegal Unicode sequence (unpaired low surrogate)"); - } else { - int code_point = 0x10000 + - ((unicode_high_surrogate & 0x03FF) << 10) + - (val & 0x03FF); - ToUTF8(code_point, &attribute_); - unicode_high_surrogate = -1; - } - } else { - if (unicode_high_surrogate != -1) { - return Error( - "illegal Unicode sequence (unpaired high surrogate)"); - } - ToUTF8(static_cast<int>(val), &attribute_); - } - break; - } - default: return Error("unknown escape code in string constant"); - } - } else { // printable chars + UTF-8 bytes - if (unicode_high_surrogate != -1) { - return Error( - "illegal Unicode sequence (unpaired high surrogate)"); - } - // reset if non-printable - attr_is_trivial_ascii_string_ &= - check_ascii_range(*cursor_, ' ', '~'); - - attribute_ += *cursor_++; - } - } - if (unicode_high_surrogate != -1) { - return Error("illegal Unicode sequence (unpaired high surrogate)"); - } - cursor_++; - if (!attr_is_trivial_ascii_string_ && !opts.allow_non_utf8 && - !ValidateUTF8(attribute_)) { - return Error("illegal UTF-8 sequence"); - } - token_ = kTokenStringConstant; - return NoError(); - } - case '/': - if (*cursor_ == '/') { - const char *start = ++cursor_; - while (*cursor_ && *cursor_ != '\n' && *cursor_ != '\r') cursor_++; - if (*start == '/') { // documentation comment - if (!seen_newline) - return Error( - "a documentation comment should be on a line on its own"); - doc_comment_.push_back(std::string(start + 1, cursor_)); - } - break; - } else if (*cursor_ == '*') { - cursor_++; - // TODO: make nested. - while (*cursor_ != '*' || cursor_[1] != '/') { - if (*cursor_ == '\n') MarkNewLine(); - if (!*cursor_) return Error("end of file in comment"); - cursor_++; - } - cursor_ += 2; - break; - } - FLATBUFFERS_FALLTHROUGH(); // else fall thru - default: - if (IsIdentifierStart(c)) { - // Collect all chars of an identifier: - const char *start = cursor_ - 1; - while (IsIdentifierStart(*cursor_) || is_digit(*cursor_)) cursor_++; - attribute_.append(start, cursor_); - token_ = kTokenIdentifier; - return NoError(); - } - - const auto has_sign = (c == '+') || (c == '-'); - if (has_sign && IsIdentifierStart(*cursor_)) { - // '-'/'+' and following identifier - it could be a predefined - // constant. Return the sign in token_, see ParseSingleValue. - return NoError(); - } - - auto dot_lvl = - (c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen - if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum? - // Parser accepts hexadecimal-floating-literal (see C++ 5.13.4). - if (is_digit(c) || has_sign || !dot_lvl) { - const auto start = cursor_ - 1; - auto start_digits = !is_digit(c) ? cursor_ : cursor_ - 1; - if (!is_digit(c) && is_digit(*cursor_)) { - start_digits = cursor_; // see digit in cursor_ position - c = *cursor_++; - } - // hex-float can't begind with '.' - auto use_hex = dot_lvl && (c == '0') && is_alpha_char(*cursor_, 'X'); - if (use_hex) start_digits = ++cursor_; // '0x' is the prefix, skip it - // Read an integer number or mantisa of float-point number. - do { - if (use_hex) { - while (is_xdigit(*cursor_)) cursor_++; - } else { - while (is_digit(*cursor_)) cursor_++; - } - } while ((*cursor_ == '.') && (++cursor_) && (--dot_lvl >= 0)); - // Exponent of float-point number. - if ((dot_lvl >= 0) && (cursor_ > start_digits)) { - // The exponent suffix of hexadecimal float number is mandatory. - if (use_hex && !dot_lvl) start_digits = cursor_; - if ((use_hex && is_alpha_char(*cursor_, 'P')) || - is_alpha_char(*cursor_, 'E')) { - dot_lvl = 0; // Emulate dot to signal about float-point number. - cursor_++; - if (*cursor_ == '+' || *cursor_ == '-') cursor_++; - start_digits = cursor_; // the exponent-part has to have digits - // Exponent is decimal integer number - while (is_digit(*cursor_)) cursor_++; - if (*cursor_ == '.') { - cursor_++; // If see a dot treat it as part of invalid number. - dot_lvl = -1; // Fall thru to Error(). - } - } - } - // Finalize. - if ((dot_lvl >= 0) && (cursor_ > start_digits)) { - attribute_.append(start, cursor_); - token_ = dot_lvl ? kTokenIntegerConstant : kTokenFloatConstant; - return NoError(); - } else { - return Error("invalid number: " + std::string(start, cursor_)); - } - } - std::string ch; - ch = c; - if (false == check_ascii_range(c, ' ', '~')) - ch = "code: " + NumToString(c); - return Error("illegal character: " + ch); - } - } -} - -// Check if a given token is next. -bool Parser::Is(int t) const { return t == token_; } - -bool Parser::IsIdent(const char *id) const { - return token_ == kTokenIdentifier && attribute_ == id; -} - -// Expect a given token to be next, consume it, or error if not present. -CheckedError Parser::Expect(int t) { - if (t != token_) { - return Error("expecting: " + TokenToString(t) + - " instead got: " + TokenToStringId(token_)); - } - NEXT(); - return NoError(); -} - -CheckedError Parser::ParseNamespacing(std::string *id, std::string *last) { - while (Is('.')) { - NEXT(); - *id += "."; - *id += attribute_; - if (last) *last = attribute_; - EXPECT(kTokenIdentifier); - } - return NoError(); -} - -EnumDef *Parser::LookupEnum(const std::string &id) { - // Search thru parent namespaces. - return LookupTableByName(enums_, id, *current_namespace_, 0); -} - -StructDef *Parser::LookupStruct(const std::string &id) const { - auto sd = structs_.Lookup(id); - if (sd) sd->refcount++; - return sd; -} - -StructDef *Parser::LookupStructThruParentNamespaces( - const std::string &id) const { - auto sd = LookupTableByName(structs_, id, *current_namespace_, 1); - if (sd) sd->refcount++; - return sd; -} - -CheckedError Parser::ParseTypeIdent(Type &type) { - std::string id = attribute_; - EXPECT(kTokenIdentifier); - ECHECK(ParseNamespacing(&id, nullptr)); - auto enum_def = LookupEnum(id); - if (enum_def) { - type = enum_def->underlying_type; - if (enum_def->is_union) type.base_type = BASE_TYPE_UNION; - } else { - type.base_type = BASE_TYPE_STRUCT; - type.struct_def = LookupCreateStruct(id); - } - return NoError(); -} - -// Parse any IDL type. -CheckedError Parser::ParseType(Type &type) { - if (token_ == kTokenIdentifier) { - if (IsIdent("bool")) { - type.base_type = BASE_TYPE_BOOL; - NEXT(); - } else if (IsIdent("byte") || IsIdent("int8")) { - type.base_type = BASE_TYPE_CHAR; - NEXT(); - } else if (IsIdent("ubyte") || IsIdent("uint8")) { - type.base_type = BASE_TYPE_UCHAR; - NEXT(); - } else if (IsIdent("short") || IsIdent("int16")) { - type.base_type = BASE_TYPE_SHORT; - NEXT(); - } else if (IsIdent("ushort") || IsIdent("uint16")) { - type.base_type = BASE_TYPE_USHORT; - NEXT(); - } else if (IsIdent("int") || IsIdent("int32")) { - type.base_type = BASE_TYPE_INT; - NEXT(); - } else if (IsIdent("uint") || IsIdent("uint32")) { - type.base_type = BASE_TYPE_UINT; - NEXT(); - } else if (IsIdent("long") || IsIdent("int64")) { - type.base_type = BASE_TYPE_LONG; - NEXT(); - } else if (IsIdent("ulong") || IsIdent("uint64")) { - type.base_type = BASE_TYPE_ULONG; - NEXT(); - } else if (IsIdent("float") || IsIdent("float32")) { - type.base_type = BASE_TYPE_FLOAT; - NEXT(); - } else if (IsIdent("double") || IsIdent("float64")) { - type.base_type = BASE_TYPE_DOUBLE; - NEXT(); - } else if (IsIdent("string")) { - type.base_type = BASE_TYPE_STRING; - NEXT(); - } else { - ECHECK(ParseTypeIdent(type)); - } - } else if (token_ == '[') { - ParseDepthGuard depth_guard(this); - ECHECK(depth_guard.Check()); - NEXT(); - Type subtype; - ECHECK(ParseType(subtype)); - if (IsSeries(subtype)) { - // We could support this, but it will complicate things, and it's - // easier to work around with a struct around the inner vector. - return Error("nested vector types not supported (wrap in table first)"); - } - if (token_ == ':') { - NEXT(); - if (token_ != kTokenIntegerConstant) { - return Error("length of fixed-length array must be an integer value"); - } - uint16_t fixed_length = 0; - bool check = StringToNumber(attribute_.c_str(), &fixed_length); - if (!check || fixed_length < 1) { - return Error( - "length of fixed-length array must be positive and fit to " - "uint16_t type"); - } - type = Type(BASE_TYPE_ARRAY, subtype.struct_def, subtype.enum_def, - fixed_length); - NEXT(); - } else { - type = Type(BASE_TYPE_VECTOR, subtype.struct_def, subtype.enum_def); - } - type.element = subtype.base_type; - EXPECT(']'); - } else { - return Error("illegal type syntax"); - } - return NoError(); -} - -CheckedError Parser::AddField(StructDef &struct_def, const std::string &name, - const Type &type, FieldDef **dest) { - auto &field = *new FieldDef(); - field.value.offset = - FieldIndexToOffset(static_cast<voffset_t>(struct_def.fields.vec.size())); - field.name = name; - field.file = struct_def.file; - field.value.type = type; - if (struct_def.fixed) { // statically compute the field offset - auto size = InlineSize(type); - auto alignment = InlineAlignment(type); - // structs_ need to have a predictable format, so we need to align to - // the largest scalar - struct_def.minalign = std::max(struct_def.minalign, alignment); - struct_def.PadLastField(alignment); - field.value.offset = static_cast<voffset_t>(struct_def.bytesize); - struct_def.bytesize += size; - } - if (struct_def.fields.Add(name, &field)) - return Error("field already exists: " + name); - *dest = &field; - return NoError(); -} - -CheckedError Parser::ParseField(StructDef &struct_def) { - std::string name = attribute_; - - if (LookupCreateStruct(name, false, false)) - return Error("field name can not be the same as table/struct name"); - - if (!IsLowerSnakeCase(name)) { - Warning("field names should be lowercase snake_case, got: " + name); - } - - std::vector<std::string> dc = doc_comment_; - EXPECT(kTokenIdentifier); - EXPECT(':'); - Type type; - ECHECK(ParseType(type)); - - if (struct_def.fixed) { - auto valid = IsScalar(type.base_type) || IsStruct(type); - if (!valid && IsArray(type)) { - const auto &elem_type = type.VectorType(); - valid |= IsScalar(elem_type.base_type) || IsStruct(elem_type); - } - if (!valid) - return Error("structs may contain only scalar or struct fields"); - } - - if (!struct_def.fixed && IsArray(type)) - return Error("fixed-length array in table must be wrapped in struct"); - - if (IsArray(type)) { - advanced_features_ |= reflection::AdvancedArrayFeatures; - if (!SupportsAdvancedArrayFeatures()) { - return Error( - "Arrays are not yet supported in all " - "the specified programming languages."); - } - } - - FieldDef *typefield = nullptr; - if (type.base_type == BASE_TYPE_UNION) { - // For union fields, add a second auto-generated field to hold the type, - // with a special suffix. - ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(), - type.enum_def->underlying_type, &typefield)); - } else if (IsVector(type) && type.element == BASE_TYPE_UNION) { - advanced_features_ |= reflection::AdvancedUnionFeatures; - // Only cpp, js and ts supports the union vector feature so far. - if (!SupportsAdvancedUnionFeatures()) { - return Error( - "Vectors of unions are not yet supported in at least one of " - "the specified programming languages."); - } - // For vector of union fields, add a second auto-generated vector field to - // hold the types, with a special suffix. - Type union_vector(BASE_TYPE_VECTOR, nullptr, type.enum_def); - union_vector.element = BASE_TYPE_UTYPE; - ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(), union_vector, - &typefield)); - } - - FieldDef *field; - ECHECK(AddField(struct_def, name, type, &field)); - - if (token_ == '=') { - NEXT(); - ECHECK(ParseSingleValue(&field->name, field->value, true)); - if (IsStruct(type) || (struct_def.fixed && field->value.constant != "0")) - return Error( - "default values are not supported for struct fields, table fields, " - "or in structs."); - if (IsString(type) || IsVector(type)) { - advanced_features_ |= reflection::DefaultVectorsAndStrings; - if (field->value.constant != "0" && field->value.constant != "null" && - !SupportsDefaultVectorsAndStrings()) { - return Error( - "Default values for strings and vectors are not supported in one " - "of the specified programming languages"); - } - } - - if (IsVector(type) && field->value.constant != "0" && - field->value.constant != "[]") { - return Error("The only supported default for vectors is `[]`."); - } - } - - // Append .0 if the value has not it (skip hex and scientific floats). - // This suffix needed for generated C++ code. - if (IsFloat(type.base_type)) { - auto &text = field->value.constant; - FLATBUFFERS_ASSERT(false == text.empty()); - auto s = text.c_str(); - while (*s == ' ') s++; - if (*s == '-' || *s == '+') s++; - // 1) A float constants (nan, inf, pi, etc) is a kind of identifier. - // 2) A float number needn't ".0" at the end if it has exponent. - if ((false == IsIdentifierStart(*s)) && - (std::string::npos == field->value.constant.find_first_of(".eEpP"))) { - field->value.constant += ".0"; - } - } - - field->doc_comment = dc; - ECHECK(ParseMetaData(&field->attributes)); - field->deprecated = field->attributes.Lookup("deprecated") != nullptr; - auto hash_name = field->attributes.Lookup("hash"); - if (hash_name) { - switch ((IsVector(type)) ? type.element : type.base_type) { - case BASE_TYPE_SHORT: - case BASE_TYPE_USHORT: { - if (FindHashFunction16(hash_name->constant.c_str()) == nullptr) - return Error("Unknown hashing algorithm for 16 bit types: " + - hash_name->constant); - break; - } - case BASE_TYPE_INT: - case BASE_TYPE_UINT: { - if (FindHashFunction32(hash_name->constant.c_str()) == nullptr) - return Error("Unknown hashing algorithm for 32 bit types: " + - hash_name->constant); - break; - } - case BASE_TYPE_LONG: - case BASE_TYPE_ULONG: { - if (FindHashFunction64(hash_name->constant.c_str()) == nullptr) - return Error("Unknown hashing algorithm for 64 bit types: " + - hash_name->constant); - break; - } - default: - return Error( - "only short, ushort, int, uint, long and ulong data types support " - "hashing."); - } - } - - // For historical convenience reasons, string keys are assumed required. - // Scalars are kDefault unless otherwise specified. - // Nonscalars are kOptional unless required; - field->key = field->attributes.Lookup("key") != nullptr; - const bool required = field->attributes.Lookup("required") != nullptr || - (IsString(type) && field->key); - const bool default_str_or_vec = - ((IsString(type) || IsVector(type)) && field->value.constant != "0"); - const bool optional = IsScalar(type.base_type) - ? (field->value.constant == "null") - : !(required || default_str_or_vec); - if (required && optional) { - return Error("Fields cannot be both optional and required."); - } - field->presence = FieldDef::MakeFieldPresence(optional, required); - - if (required && (struct_def.fixed || IsScalar(type.base_type))) { - return Error("only non-scalar fields in tables may be 'required'"); - } - if (field->key) { - if (struct_def.has_key) return Error("only one field may be set as 'key'"); - struct_def.has_key = true; - if (!IsScalar(type.base_type) && !IsString(type)) { - return Error("'key' field must be string or scalar type"); - } - } - - if (field->IsScalarOptional()) { - advanced_features_ |= reflection::OptionalScalars; - if (type.enum_def && type.enum_def->Lookup("null")) { - FLATBUFFERS_ASSERT(IsInteger(type.base_type)); - return Error( - "the default 'null' is reserved for declaring optional scalar " - "fields, it conflicts with declaration of enum '" + - type.enum_def->name + "'."); - } - if (field->attributes.Lookup("key")) { - return Error( - "only a non-optional scalar field can be used as a 'key' field"); - } - if (!SupportsOptionalScalars()) { - return Error( - "Optional scalars are not yet supported in at least one the of " - "the specified programming languages."); - } - } - - if (type.enum_def) { - // Verify the enum's type and default value. - const std::string &constant = field->value.constant; - if (type.base_type == BASE_TYPE_UNION) { - if (constant != "0") { return Error("Union defaults must be NONE"); } - } else if (IsVector(type)) { - if (constant != "0" && constant != "[]") { - return Error("Vector defaults may only be `[]`."); - } - } else if (IsArray(type)) { - if (constant != "0") { - return Error("Array defaults are not supported yet."); - } - } else { - if (!IsInteger(type.base_type)) { - return Error("Enums must have integer base types"); - } - // Optional and bitflags enums may have default constants that are not - // their specified variants. - if (!field->IsOptional() && - type.enum_def->attributes.Lookup("bit_flags") == nullptr) { - if (type.enum_def->FindByValue(constant) == nullptr) { - return Error("default value of `" + constant + "` for " + "field `" + - name + "` is not part of enum `" + type.enum_def->name + - "`."); - } - } - } - } - - if (field->deprecated && struct_def.fixed) - return Error("can't deprecate fields in a struct"); - - auto cpp_type = field->attributes.Lookup("cpp_type"); - if (cpp_type) { - if (!hash_name) - return Error("cpp_type can only be used with a hashed field"); - /// forcing cpp_ptr_type to 'naked' if unset - auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type"); - if (!cpp_ptr_type) { - auto val = new Value(); - val->type = cpp_type->type; - val->constant = "naked"; - field->attributes.Add("cpp_ptr_type", val); - } - } - - field->shared = field->attributes.Lookup("shared") != nullptr; - if (field->shared && field->value.type.base_type != BASE_TYPE_STRING) - return Error("shared can only be defined on strings"); - - auto field_native_custom_alloc = - field->attributes.Lookup("native_custom_alloc"); - if (field_native_custom_alloc) - return Error( - "native_custom_alloc can only be used with a table or struct " - "definition"); - - field->native_inline = field->attributes.Lookup("native_inline") != nullptr; - if (field->native_inline && !IsStruct(field->value.type)) - return Error("native_inline can only be defined on structs"); - - auto nested = field->attributes.Lookup("nested_flatbuffer"); - if (nested) { - if (nested->type.base_type != BASE_TYPE_STRING) - return Error( - "nested_flatbuffer attribute must be a string (the root type)"); - if (type.base_type != BASE_TYPE_VECTOR || type.element != BASE_TYPE_UCHAR) - return Error( - "nested_flatbuffer attribute may only apply to a vector of ubyte"); - // This will cause an error if the root type of the nested flatbuffer - // wasn't defined elsewhere. - field->nested_flatbuffer = LookupCreateStruct(nested->constant); - } - - if (field->attributes.Lookup("flexbuffer")) { - field->flexbuffer = true; - uses_flexbuffers_ = true; - if (type.base_type != BASE_TYPE_VECTOR || type.element != BASE_TYPE_UCHAR) - return Error("flexbuffer attribute may only apply to a vector of ubyte"); - } - - if (typefield) { - if (!IsScalar(typefield->value.type.base_type)) { - // this is a union vector field - typefield->presence = field->presence; - } - // If this field is a union, and it has a manually assigned id, - // the automatically added type field should have an id as well (of N - 1). - auto attr = field->attributes.Lookup("id"); - if (attr) { - const auto &id_str = attr->constant; - voffset_t id = 0; - const auto done = !atot(id_str.c_str(), *this, &id).Check(); - if (done && id > 0) { - auto val = new Value(); - val->type = attr->type; - val->constant = NumToString(id - 1); - typefield->attributes.Add("id", val); - } else { - return Error( - "a union type effectively adds two fields with non-negative ids, " - "its id must be that of the second field (the first field is " - "the type field and not explicitly declared in the schema);\n" - "field: " + - field->name + ", id: " + id_str); - } - } - // if this field is a union that is deprecated, - // the automatically added type field should be deprecated as well - if (field->deprecated) { typefield->deprecated = true; } - } - - EXPECT(';'); - return NoError(); -} - -CheckedError Parser::ParseString(Value &val, bool use_string_pooling) { - auto s = attribute_; - EXPECT(kTokenStringConstant); - if (use_string_pooling) { - val.constant = NumToString(builder_.CreateSharedString(s).o); - } else { - val.constant = NumToString(builder_.CreateString(s).o); - } - return NoError(); -} - -CheckedError Parser::ParseComma() { - if (!opts.protobuf_ascii_alike) EXPECT(','); - return NoError(); -} - -CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field, - size_t parent_fieldn, - const StructDef *parent_struct_def, - uoffset_t count, bool inside_vector) { - switch (val.type.base_type) { - case BASE_TYPE_UNION: { - FLATBUFFERS_ASSERT(field); - std::string constant; - Vector<uint8_t> *vector_of_union_types = nullptr; - // Find corresponding type field we may have already parsed. - for (auto elem = field_stack_.rbegin() + count; - elem != field_stack_.rbegin() + parent_fieldn + count; ++elem) { - auto &type = elem->second->value.type; - if (type.enum_def == val.type.enum_def) { - if (inside_vector) { - if (IsVector(type) && type.element == BASE_TYPE_UTYPE) { - // Vector of union type field. - uoffset_t offset; - ECHECK(atot(elem->first.constant.c_str(), *this, &offset)); - vector_of_union_types = reinterpret_cast<Vector<uint8_t> *>( - builder_.GetCurrentBufferPointer() + builder_.GetSize() - - offset); - break; - } - } else { - if (type.base_type == BASE_TYPE_UTYPE) { - // Union type field. - constant = elem->first.constant; - break; - } - } - } - } - if (constant.empty() && !inside_vector) { - // We haven't seen the type field yet. Sadly a lot of JSON writers - // output these in alphabetical order, meaning it comes after this - // value. So we scan past the value to find it, then come back here. - // We currently don't do this for vectors of unions because the - // scanning/serialization logic would get very complicated. - auto type_name = field->name + UnionTypeFieldSuffix(); - FLATBUFFERS_ASSERT(parent_struct_def); - auto type_field = parent_struct_def->fields.Lookup(type_name); - FLATBUFFERS_ASSERT(type_field); // Guaranteed by ParseField(). - // Remember where we are in the source file, so we can come back here. - auto backup = *static_cast<ParserState *>(this); - ECHECK(SkipAnyJsonValue()); // The table. - ECHECK(ParseComma()); - auto next_name = attribute_; - if (Is(kTokenStringConstant)) { - NEXT(); - } else { - EXPECT(kTokenIdentifier); - } - if (next_name == type_name) { - EXPECT(':'); - ParseDepthGuard depth_guard(this); - ECHECK(depth_guard.Check()); - Value type_val = type_field->value; - ECHECK(ParseAnyValue(type_val, type_field, 0, nullptr, 0)); - constant = type_val.constant; - // Got the information we needed, now rewind: - *static_cast<ParserState *>(this) = backup; - } - } - if (constant.empty() && !vector_of_union_types) { - return Error("missing type field for this union value: " + field->name); - } - uint8_t enum_idx; - if (vector_of_union_types) { - enum_idx = vector_of_union_types->Get(count); - } else { - ECHECK(atot(constant.c_str(), *this, &enum_idx)); - } - auto enum_val = val.type.enum_def->ReverseLookup(enum_idx, true); - if (!enum_val) return Error("illegal type id for: " + field->name); - if (enum_val->union_type.base_type == BASE_TYPE_STRUCT) { - ECHECK(ParseTable(*enum_val->union_type.struct_def, &val.constant, - nullptr)); - if (enum_val->union_type.struct_def->fixed) { - // All BASE_TYPE_UNION values are offsets, so turn this into one. - SerializeStruct(*enum_val->union_type.struct_def, val); - builder_.ClearOffsets(); - val.constant = NumToString(builder_.GetSize()); - } - } else if (IsString(enum_val->union_type)) { - ECHECK(ParseString(val, field->shared)); - } else { - FLATBUFFERS_ASSERT(false); - } - break; - } - case BASE_TYPE_STRUCT: - ECHECK(ParseTable(*val.type.struct_def, &val.constant, nullptr)); - break; - case BASE_TYPE_STRING: { - ECHECK(ParseString(val, field->shared)); - break; - } - case BASE_TYPE_VECTOR: { - uoffset_t off; - ECHECK(ParseVector(val.type.VectorType(), &off, field, parent_fieldn)); - val.constant = NumToString(off); - break; - } - case BASE_TYPE_ARRAY: { - ECHECK(ParseArray(val)); - break; - } - case BASE_TYPE_INT: - case BASE_TYPE_UINT: - case BASE_TYPE_LONG: - case BASE_TYPE_ULONG: { - if (field && field->attributes.Lookup("hash") && - (token_ == kTokenIdentifier || token_ == kTokenStringConstant)) { - ECHECK(ParseHash(val, field)); - } else { - ECHECK(ParseSingleValue(field ? &field->name : nullptr, val, false)); - } - break; - } - default: - ECHECK(ParseSingleValue(field ? &field->name : nullptr, val, false)); - break; - } - return NoError(); -} - -void Parser::SerializeStruct(const StructDef &struct_def, const Value &val) { - SerializeStruct(builder_, struct_def, val); -} - -void Parser::SerializeStruct(FlatBufferBuilder &builder, - const StructDef &struct_def, const Value &val) { - FLATBUFFERS_ASSERT(val.constant.length() == struct_def.bytesize); - builder.Align(struct_def.minalign); - builder.PushBytes(reinterpret_cast<const uint8_t *>(val.constant.c_str()), - struct_def.bytesize); - builder.AddStructOffset(val.offset, builder.GetSize()); -} - -template<typename F> -CheckedError Parser::ParseTableDelimiters(size_t &fieldn, - const StructDef *struct_def, F body) { - // We allow tables both as JSON object{ .. } with field names - // or vector[..] with all fields in order - char terminator = '}'; - bool is_nested_vector = struct_def && Is('['); - if (is_nested_vector) { - NEXT(); - terminator = ']'; - } else { - EXPECT('{'); - } - for (;;) { - if ((!opts.strict_json || !fieldn) && Is(terminator)) break; - std::string name; - if (is_nested_vector) { - if (fieldn >= struct_def->fields.vec.size()) { - return Error("too many unnamed fields in nested array"); - } - name = struct_def->fields.vec[fieldn]->name; - } else { - name = attribute_; - if (Is(kTokenStringConstant)) { - NEXT(); - } else { - EXPECT(opts.strict_json ? kTokenStringConstant : kTokenIdentifier); - } - if (!opts.protobuf_ascii_alike || !(Is('{') || Is('['))) EXPECT(':'); - } - ECHECK(body(name, fieldn, struct_def)); - if (Is(terminator)) break; - ECHECK(ParseComma()); - } - NEXT(); - if (is_nested_vector && fieldn != struct_def->fields.vec.size()) { - return Error("wrong number of unnamed fields in table vector"); - } - return NoError(); -} - -CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value, - uoffset_t *ovalue) { - ParseDepthGuard depth_guard(this); - ECHECK(depth_guard.Check()); - - size_t fieldn_outer = 0; - auto err = ParseTableDelimiters( - fieldn_outer, &struct_def, - [&](const std::string &name, size_t &fieldn, - const StructDef *struct_def_inner) -> CheckedError { - if (name == "$schema") { - ECHECK(Expect(kTokenStringConstant)); - return NoError(); - } - auto field = struct_def_inner->fields.Lookup(name); - if (!field) { - if (!opts.skip_unexpected_fields_in_json) { - return Error("unknown field: " + name); - } else { - ECHECK(SkipAnyJsonValue()); - } - } else { - if (IsIdent("null") && !IsScalar(field->value.type.base_type)) { - ECHECK(Next()); // Ignore this field. - } else { - Value val = field->value; - if (field->flexbuffer) { - flexbuffers::Builder builder(1024, - flexbuffers::BUILDER_FLAG_SHARE_ALL); - ECHECK(ParseFlexBufferValue(&builder)); - builder.Finish(); - // Force alignment for nested flexbuffer - builder_.ForceVectorAlignment(builder.GetSize(), sizeof(uint8_t), - sizeof(largest_scalar_t)); - auto off = builder_.CreateVector(builder.GetBuffer()); - val.constant = NumToString(off.o); - } else if (field->nested_flatbuffer) { - ECHECK( - ParseNestedFlatbuffer(val, field, fieldn, struct_def_inner)); - } else { - ECHECK(ParseAnyValue(val, field, fieldn, struct_def_inner, 0)); - } - // Hardcoded insertion-sort with error-check. - // If fields are specified in order, then this loop exits - // immediately. - auto elem = field_stack_.rbegin(); - for (; elem != field_stack_.rbegin() + fieldn; ++elem) { - auto existing_field = elem->second; - if (existing_field == field) - return Error("field set more than once: " + field->name); - if (existing_field->value.offset < field->value.offset) break; - } - // Note: elem points to before the insertion point, thus .base() - // points to the correct spot. - field_stack_.insert(elem.base(), std::make_pair(val, field)); - fieldn++; - } - } - return NoError(); - }); - ECHECK(err); - - // Check if all required fields are parsed. - for (auto field_it = struct_def.fields.vec.begin(); - field_it != struct_def.fields.vec.end(); ++field_it) { - auto required_field = *field_it; - if (!required_field->IsRequired()) { continue; } - bool found = false; - for (auto pf_it = field_stack_.end() - fieldn_outer; - pf_it != field_stack_.end(); ++pf_it) { - auto parsed_field = pf_it->second; - if (parsed_field == required_field) { - found = true; - break; - } - } - if (!found) { - return Error("required field is missing: " + required_field->name + - " in " + struct_def.name); - } - } - - if (struct_def.fixed && fieldn_outer != struct_def.fields.vec.size()) - return Error("struct: wrong number of initializers: " + struct_def.name); - - auto start = struct_def.fixed ? builder_.StartStruct(struct_def.minalign) - : builder_.StartTable(); - - for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1; size; - size /= 2) { - // Go through elements in reverse, since we're building the data backwards. - for (auto it = field_stack_.rbegin(); - it != field_stack_.rbegin() + fieldn_outer; ++it) { - auto &field_value = it->first; - auto field = it->second; - if (!struct_def.sortbysize || - size == SizeOf(field_value.type.base_type)) { - switch (field_value.type.base_type) { - // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - builder_.Pad(field->padding); \ - if (struct_def.fixed) { \ - CTYPE val; \ - ECHECK(atot(field_value.constant.c_str(), *this, &val)); \ - builder_.PushElement(val); \ - } else { \ - CTYPE val, valdef; \ - ECHECK(atot(field_value.constant.c_str(), *this, &val)); \ - ECHECK(atot(field->value.constant.c_str(), *this, &valdef)); \ - builder_.AddElement(field_value.offset, val, valdef); \ - } \ - break; - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - builder_.Pad(field->padding); \ - if (IsStruct(field->value.type)) { \ - SerializeStruct(*field->value.type.struct_def, field_value); \ - } else { \ - CTYPE val; \ - ECHECK(atot(field_value.constant.c_str(), *this, &val)); \ - builder_.AddOffset(field_value.offset, val); \ - } \ - break; - FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - case BASE_TYPE_ARRAY: - builder_.Pad(field->padding); - builder_.PushBytes( - reinterpret_cast<const uint8_t*>(field_value.constant.c_str()), - InlineSize(field_value.type)); - break; - // clang-format on - } - } - } - } - for (size_t i = 0; i < fieldn_outer; i++) field_stack_.pop_back(); - - if (struct_def.fixed) { - builder_.ClearOffsets(); - builder_.EndStruct(); - FLATBUFFERS_ASSERT(value); - // Temporarily store this struct in the value string, since it is to - // be serialized in-place elsewhere. - value->assign( - reinterpret_cast<const char *>(builder_.GetCurrentBufferPointer()), - struct_def.bytesize); - builder_.PopBytes(struct_def.bytesize); - FLATBUFFERS_ASSERT(!ovalue); - } else { - auto val = builder_.EndTable(start); - if (ovalue) *ovalue = val; - if (value) *value = NumToString(val); - } - return NoError(); -} - -template<typename F> -CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) { - EXPECT('['); - for (;;) { - if ((!opts.strict_json || !count) && Is(']')) break; - ECHECK(body(count)); - count++; - if (Is(']')) break; - ECHECK(ParseComma()); - } - NEXT(); - return NoError(); -} - -static bool CompareSerializedScalars(const uint8_t *a, const uint8_t *b, - const FieldDef &key) { - switch (key.value.type.base_type) { -#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_##ENUM: { \ - CTYPE def = static_cast<CTYPE>(0); \ - if (!a || !b) { StringToNumber(key.value.constant.c_str(), &def); } \ - const auto av = a ? ReadScalar<CTYPE>(a) : def; \ - const auto bv = b ? ReadScalar<CTYPE>(b) : def; \ - return av < bv; \ - } - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) -#undef FLATBUFFERS_TD - default: { - FLATBUFFERS_ASSERT(false && "scalar type expected"); - return false; - } - } -} - -static bool CompareTablesByScalarKey(const Offset<Table> *_a, - const Offset<Table> *_b, - const FieldDef &key) { - const voffset_t offset = key.value.offset; - // Indirect offset pointer to table pointer. - auto a = reinterpret_cast<const uint8_t *>(_a) + ReadScalar<uoffset_t>(_a); - auto b = reinterpret_cast<const uint8_t *>(_b) + ReadScalar<uoffset_t>(_b); - // Fetch field address from table. - a = reinterpret_cast<const Table *>(a)->GetAddressOf(offset); - b = reinterpret_cast<const Table *>(b)->GetAddressOf(offset); - return CompareSerializedScalars(a, b, key); -} - -static bool CompareTablesByStringKey(const Offset<Table> *_a, - const Offset<Table> *_b, - const FieldDef &key) { - const voffset_t offset = key.value.offset; - // Indirect offset pointer to table pointer. - auto a = reinterpret_cast<const uint8_t *>(_a) + ReadScalar<uoffset_t>(_a); - auto b = reinterpret_cast<const uint8_t *>(_b) + ReadScalar<uoffset_t>(_b); - // Fetch field address from table. - a = reinterpret_cast<const Table *>(a)->GetAddressOf(offset); - b = reinterpret_cast<const Table *>(b)->GetAddressOf(offset); - if (a && b) { - // Indirect offset pointer to string pointer. - a += ReadScalar<uoffset_t>(a); - b += ReadScalar<uoffset_t>(b); - return *reinterpret_cast<const String *>(a) < - *reinterpret_cast<const String *>(b); - } else { - return a ? true : false; - } -} - -static void SwapSerializedTables(Offset<Table> *a, Offset<Table> *b) { - // These are serialized offsets, so are relative where they are - // stored in memory, so compute the distance between these pointers: - ptrdiff_t diff = (b - a) * sizeof(Offset<Table>); - FLATBUFFERS_ASSERT(diff >= 0); // Guaranteed by SimpleQsort. - auto udiff = static_cast<uoffset_t>(diff); - a->o = EndianScalar(ReadScalar<uoffset_t>(a) - udiff); - b->o = EndianScalar(ReadScalar<uoffset_t>(b) + udiff); - std::swap(*a, *b); -} - -// See below for why we need our own sort :( -template<typename T, typename F, typename S> -void SimpleQsort(T *begin, T *end, size_t width, F comparator, S swapper) { - if (end - begin <= static_cast<ptrdiff_t>(width)) return; - auto l = begin + width; - auto r = end; - while (l < r) { - if (comparator(begin, l)) { - r -= width; - swapper(l, r); - } else { - l += width; - } - } - l -= width; - swapper(begin, l); - SimpleQsort(begin, l, width, comparator, swapper); - SimpleQsort(r, end, width, comparator, swapper); -} - -CheckedError Parser::ParseAlignAttribute(const std::string &align_constant, - size_t min_align, size_t *align) { - // Use uint8_t to avoid problems with size_t==`unsigned long` on LP64. - uint8_t align_value; - if (StringToNumber(align_constant.c_str(), &align_value) && - VerifyAlignmentRequirements(static_cast<size_t>(align_value), - min_align)) { - *align = align_value; - return NoError(); - } - return Error("unexpected force_align value '" + align_constant + - "', alignment must be a power of two integer ranging from the " - "type\'s natural alignment " + - NumToString(min_align) + " to " + - NumToString(FLATBUFFERS_MAX_ALIGNMENT)); -} - -CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue, - FieldDef *field, size_t fieldn) { - uoffset_t count = 0; - auto err = ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError { - Value val; - val.type = type; - ECHECK(ParseAnyValue(val, field, fieldn, nullptr, count, true)); - field_stack_.push_back(std::make_pair(val, nullptr)); - return NoError(); - }); - ECHECK(err); - - const size_t len = count * InlineSize(type) / InlineAlignment(type); - const size_t elemsize = InlineAlignment(type); - const auto force_align = field->attributes.Lookup("force_align"); - if (force_align) { - size_t align; - ECHECK(ParseAlignAttribute(force_align->constant, 1, &align)); - if (align > 1) { builder_.ForceVectorAlignment(len, elemsize, align); } - } - - builder_.StartVector(len, elemsize); - for (uoffset_t i = 0; i < count; i++) { - // start at the back, since we're building the data backwards. - auto &val = field_stack_.back().first; - switch (val.type.base_type) { - // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE,...) \ - case BASE_TYPE_ ## ENUM: \ - if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \ - else { \ - CTYPE elem; \ - ECHECK(atot(val.constant.c_str(), *this, &elem)); \ - builder_.PushElement(elem); \ - } \ - break; - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - // clang-format on - } - field_stack_.pop_back(); - } - - builder_.ClearOffsets(); - *ovalue = builder_.EndVector(count); - - if (type.base_type == BASE_TYPE_STRUCT && type.struct_def->has_key) { - // We should sort this vector. Find the key first. - const FieldDef *key = nullptr; - for (auto it = type.struct_def->fields.vec.begin(); - it != type.struct_def->fields.vec.end(); ++it) { - if ((*it)->key) { - key = (*it); - break; - } - } - FLATBUFFERS_ASSERT(key); - // Now sort it. - // We can't use std::sort because for structs the size is not known at - // compile time, and for tables our iterators dereference offsets, so can't - // be used to swap elements. - // And we can't use C qsort either, since that would force use to use - // globals, making parsing thread-unsafe. - // So for now, we use SimpleQsort above. - // TODO: replace with something better, preferably not recursive. - - if (type.struct_def->fixed) { - const voffset_t offset = key->value.offset; - const size_t struct_size = type.struct_def->bytesize; - auto v = - reinterpret_cast<VectorOfAny *>(builder_.GetCurrentBufferPointer()); - SimpleQsort<uint8_t>( - v->Data(), v->Data() + v->size() * type.struct_def->bytesize, - type.struct_def->bytesize, - [offset, key](const uint8_t *a, const uint8_t *b) -> bool { - return CompareSerializedScalars(a + offset, b + offset, *key); - }, - [struct_size](uint8_t *a, uint8_t *b) { - // FIXME: faster? - for (size_t i = 0; i < struct_size; i++) { std::swap(a[i], b[i]); } - }); - } else { - auto v = reinterpret_cast<Vector<Offset<Table>> *>( - builder_.GetCurrentBufferPointer()); - // Here also can't use std::sort. We do have an iterator type for it, - // but it is non-standard as it will dereference the offsets, and thus - // can't be used to swap elements. - if (key->value.type.base_type == BASE_TYPE_STRING) { - SimpleQsort<Offset<Table>>( - v->data(), v->data() + v->size(), 1, - [key](const Offset<Table> *_a, const Offset<Table> *_b) -> bool { - return CompareTablesByStringKey(_a, _b, *key); - }, - SwapSerializedTables); - } else { - SimpleQsort<Offset<Table>>( - v->data(), v->data() + v->size(), 1, - [key](const Offset<Table> *_a, const Offset<Table> *_b) -> bool { - return CompareTablesByScalarKey(_a, _b, *key); - }, - SwapSerializedTables); - } - } - } - return NoError(); -} - -CheckedError Parser::ParseArray(Value &array) { - std::vector<Value> stack; - FlatBufferBuilder builder; - const auto &type = array.type.VectorType(); - auto length = array.type.fixed_length; - uoffset_t count = 0; - auto err = ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError { - vector_emplace_back(&stack, Value()); - auto &val = stack.back(); - val.type = type; - if (IsStruct(type)) { - ECHECK(ParseTable(*val.type.struct_def, &val.constant, nullptr)); - } else { - ECHECK(ParseSingleValue(nullptr, val, false)); - } - return NoError(); - }); - ECHECK(err); - if (length != count) return Error("Fixed-length array size is incorrect."); - - for (auto it = stack.rbegin(); it != stack.rend(); ++it) { - auto &val = *it; - // clang-format off - switch (val.type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - if (IsStruct(val.type)) { \ - SerializeStruct(builder, *val.type.struct_def, val); \ - } else { \ - CTYPE elem; \ - ECHECK(atot(val.constant.c_str(), *this, &elem)); \ - builder.PushElement(elem); \ - } \ - break; - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - default: FLATBUFFERS_ASSERT(0); - } - // clang-format on - } - - array.constant.assign( - reinterpret_cast<const char *>(builder.GetCurrentBufferPointer()), - InlineSize(array.type)); - return NoError(); -} - -CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field, - size_t fieldn, - const StructDef *parent_struct_def) { - if (token_ == '[') { // backwards compat for 'legacy' ubyte buffers - ECHECK(ParseAnyValue(val, field, fieldn, parent_struct_def, 0)); - } else { - auto cursor_at_value_begin = cursor_; - ECHECK(SkipAnyJsonValue()); - std::string substring(cursor_at_value_begin - 1, cursor_ - 1); - - // Create and initialize new parser - Parser nested_parser; - FLATBUFFERS_ASSERT(field->nested_flatbuffer); - nested_parser.root_struct_def_ = field->nested_flatbuffer; - nested_parser.enums_ = enums_; - nested_parser.opts = opts; - nested_parser.uses_flexbuffers_ = uses_flexbuffers_; - nested_parser.parse_depth_counter_ = parse_depth_counter_; - // Parse JSON substring into new flatbuffer builder using nested_parser - bool ok = nested_parser.Parse(substring.c_str(), nullptr, nullptr); - - // Clean nested_parser to avoid deleting the elements in - // the SymbolTables on destruction - nested_parser.enums_.dict.clear(); - nested_parser.enums_.vec.clear(); - - if (!ok) { ECHECK(Error(nested_parser.error_)); } - // Force alignment for nested flatbuffer - builder_.ForceVectorAlignment( - nested_parser.builder_.GetSize(), sizeof(uint8_t), - nested_parser.builder_.GetBufferMinAlignment()); - - auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(), - nested_parser.builder_.GetSize()); - val.constant = NumToString(off.o); - } - return NoError(); -} - -CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) { - if (Is('(')) { - NEXT(); - for (;;) { - auto name = attribute_; - if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant))) - return Error("attribute name must be either identifier or string: " + - name); - if (known_attributes_.find(name) == known_attributes_.end()) - return Error("user define attributes must be declared before use: " + - name); - NEXT(); - auto e = new Value(); - if (attributes->Add(name, e)) Warning("attribute already found: " + name); - if (Is(':')) { - NEXT(); - ECHECK(ParseSingleValue(&name, *e, true)); - } - if (Is(')')) { - NEXT(); - break; - } - EXPECT(','); - } - } - return NoError(); -} - -CheckedError Parser::ParseEnumFromString(const Type &type, - std::string *result) { - const auto base_type = - type.enum_def ? type.enum_def->underlying_type.base_type : type.base_type; - if (!IsInteger(base_type)) return Error("not a valid value for this field"); - uint64_t u64 = 0; - for (size_t pos = 0; pos != std::string::npos;) { - const auto delim = attribute_.find_first_of(' ', pos); - const auto last = (std::string::npos == delim); - auto word = attribute_.substr(pos, !last ? delim - pos : std::string::npos); - pos = !last ? delim + 1 : std::string::npos; - const EnumVal *ev = nullptr; - if (type.enum_def) { - ev = type.enum_def->Lookup(word); - } else { - auto dot = word.find_first_of('.'); - if (std::string::npos == dot) - return Error("enum values need to be qualified by an enum type"); - auto enum_def_str = word.substr(0, dot); - const auto enum_def = LookupEnum(enum_def_str); - if (!enum_def) return Error("unknown enum: " + enum_def_str); - auto enum_val_str = word.substr(dot + 1); - ev = enum_def->Lookup(enum_val_str); - } - if (!ev) return Error("unknown enum value: " + word); - u64 |= ev->GetAsUInt64(); - } - *result = IsUnsigned(base_type) ? NumToString(u64) - : NumToString(static_cast<int64_t>(u64)); - return NoError(); -} - -CheckedError Parser::ParseHash(Value &e, FieldDef *field) { - FLATBUFFERS_ASSERT(field); - Value *hash_name = field->attributes.Lookup("hash"); - switch (e.type.base_type) { - case BASE_TYPE_SHORT: { - auto hash = FindHashFunction16(hash_name->constant.c_str()); - int16_t hashed_value = static_cast<int16_t>(hash(attribute_.c_str())); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_USHORT: { - auto hash = FindHashFunction16(hash_name->constant.c_str()); - uint16_t hashed_value = hash(attribute_.c_str()); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_INT: { - auto hash = FindHashFunction32(hash_name->constant.c_str()); - int32_t hashed_value = static_cast<int32_t>(hash(attribute_.c_str())); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_UINT: { - auto hash = FindHashFunction32(hash_name->constant.c_str()); - uint32_t hashed_value = hash(attribute_.c_str()); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_LONG: { - auto hash = FindHashFunction64(hash_name->constant.c_str()); - int64_t hashed_value = static_cast<int64_t>(hash(attribute_.c_str())); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_ULONG: { - auto hash = FindHashFunction64(hash_name->constant.c_str()); - uint64_t hashed_value = hash(attribute_.c_str()); - e.constant = NumToString(hashed_value); - break; - } - default: FLATBUFFERS_ASSERT(0); - } - NEXT(); - return NoError(); -} - -CheckedError Parser::TokenError() { - return Error("cannot parse value starting with: " + TokenToStringId(token_)); -} - -// Re-pack helper (ParseSingleValue) to normalize defaults of scalars. -template<typename T> inline void SingleValueRepack(Value &e, T val) { - // Remove leading zeros. - if (IsInteger(e.type.base_type)) { e.constant = NumToString(val); } -} -#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) -// Normalize defaults NaN to unsigned quiet-NaN(0) if value was parsed from -// hex-float literal. -static inline void SingleValueRepack(Value &e, float val) { - if (val != val) e.constant = "nan"; -} -static inline void SingleValueRepack(Value &e, double val) { - if (val != val) e.constant = "nan"; -} -#endif - -CheckedError Parser::ParseFunction(const std::string *name, Value &e) { - ParseDepthGuard depth_guard(this); - ECHECK(depth_guard.Check()); - - // Copy name, attribute will be changed on NEXT(). - const auto functionname = attribute_; - if (!IsFloat(e.type.base_type)) { - return Error(functionname + ": type of argument mismatch, expecting: " + - kTypeNames[BASE_TYPE_DOUBLE] + - ", found: " + kTypeNames[e.type.base_type] + - ", name: " + (name ? *name : "") + ", value: " + e.constant); - } - NEXT(); - EXPECT('('); - ECHECK(ParseSingleValue(name, e, false)); - EXPECT(')'); - // calculate with double precision - double x, y = 0.0; - ECHECK(atot(e.constant.c_str(), *this, &x)); - // clang-format off - auto func_match = false; - #define FLATBUFFERS_FN_DOUBLE(name, op) \ - if (!func_match && functionname == name) { y = op; func_match = true; } - FLATBUFFERS_FN_DOUBLE("deg", x / kPi * 180); - FLATBUFFERS_FN_DOUBLE("rad", x * kPi / 180); - FLATBUFFERS_FN_DOUBLE("sin", sin(x)); - FLATBUFFERS_FN_DOUBLE("cos", cos(x)); - FLATBUFFERS_FN_DOUBLE("tan", tan(x)); - FLATBUFFERS_FN_DOUBLE("asin", asin(x)); - FLATBUFFERS_FN_DOUBLE("acos", acos(x)); - FLATBUFFERS_FN_DOUBLE("atan", atan(x)); - // TODO(wvo): add more useful conversion functions here. - #undef FLATBUFFERS_FN_DOUBLE - // clang-format on - if (true != func_match) { - return Error(std::string("Unknown conversion function: ") + functionname + - ", field name: " + (name ? *name : "") + - ", value: " + e.constant); - } - e.constant = NumToString(y); - return NoError(); -} - -CheckedError Parser::TryTypedValue(const std::string *name, int dtoken, - bool check, Value &e, BaseType req, - bool *destmatch) { - FLATBUFFERS_ASSERT(*destmatch == false && dtoken == token_); - *destmatch = true; - e.constant = attribute_; - // Check token match - if (!check) { - if (e.type.base_type == BASE_TYPE_NONE) { - e.type.base_type = req; - } else { - return Error(std::string("type mismatch: expecting: ") + - kTypeNames[e.type.base_type] + - ", found: " + kTypeNames[req] + - ", name: " + (name ? *name : "") + ", value: " + e.constant); - } - } - // The exponent suffix of hexadecimal float-point number is mandatory. - // A hex-integer constant is forbidden as an initializer of float number. - if ((kTokenFloatConstant != dtoken) && IsFloat(e.type.base_type)) { - const auto &s = e.constant; - const auto k = s.find_first_of("0123456789."); - if ((std::string::npos != k) && (s.length() > (k + 1)) && - (s[k] == '0' && is_alpha_char(s[k + 1], 'X')) && - (std::string::npos == s.find_first_of("pP", k + 2))) { - return Error( - "invalid number, the exponent suffix of hexadecimal " - "floating-point literals is mandatory: \"" + - s + "\""); - } - } - NEXT(); - return NoError(); -} - -CheckedError Parser::ParseSingleValue(const std::string *name, Value &e, - bool check_now) { - if (token_ == '+' || token_ == '-') { - const char sign = static_cast<char>(token_); - // Get an indentifier: NAN, INF, or function name like cos/sin/deg. - NEXT(); - if (token_ != kTokenIdentifier) return Error("constant name expected"); - attribute_.insert(size_t(0), size_t(1), sign); - } - - const auto in_type = e.type.base_type; - const auto is_tok_ident = (token_ == kTokenIdentifier); - const auto is_tok_string = (token_ == kTokenStringConstant); - - // First see if this could be a conversion function. - if (is_tok_ident && *cursor_ == '(') { return ParseFunction(name, e); } - - // clang-format off - auto match = false; - - #define IF_ECHECK_(force, dtoken, check, req) \ - if (!match && ((dtoken) == token_) && ((check) || IsConstTrue(force))) \ - ECHECK(TryTypedValue(name, dtoken, check, e, req, &match)) - #define TRY_ECHECK(dtoken, check, req) IF_ECHECK_(false, dtoken, check, req) - #define FORCE_ECHECK(dtoken, check, req) IF_ECHECK_(true, dtoken, check, req) - // clang-format on - - if (is_tok_ident || is_tok_string) { - const auto kTokenStringOrIdent = token_; - // The string type is a most probable type, check it first. - TRY_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING, - BASE_TYPE_STRING); - - // avoid escaped and non-ascii in the string - if (!match && is_tok_string && IsScalar(in_type) && - !attr_is_trivial_ascii_string_) { - return Error( - std::string("type mismatch or invalid value, an initializer of " - "non-string field must be trivial ASCII string: type: ") + - kTypeNames[in_type] + ", name: " + (name ? *name : "") + - ", value: " + attribute_); - } - - // A boolean as true/false. Boolean as Integer check below. - if (!match && IsBool(in_type)) { - auto is_true = attribute_ == "true"; - if (is_true || attribute_ == "false") { - attribute_ = is_true ? "1" : "0"; - // accepts both kTokenStringConstant and kTokenIdentifier - TRY_ECHECK(kTokenStringOrIdent, IsBool(in_type), BASE_TYPE_BOOL); - } - } - // Check for optional scalars. - if (!match && IsScalar(in_type) && attribute_ == "null") { - e.constant = "null"; - NEXT(); - match = true; - } - // Check if this could be a string/identifier enum value. - // Enum can have only true integer base type. - if (!match && IsInteger(in_type) && !IsBool(in_type) && - IsIdentifierStart(*attribute_.c_str())) { - ECHECK(ParseEnumFromString(e.type, &e.constant)); - NEXT(); - match = true; - } - // Parse a float/integer number from the string. - // A "scalar-in-string" value needs extra checks. - if (!match && is_tok_string && IsScalar(in_type)) { - // Strip trailing whitespaces from attribute_. - auto last_non_ws = attribute_.find_last_not_of(' '); - if (std::string::npos != last_non_ws) attribute_.resize(last_non_ws + 1); - if (IsFloat(e.type.base_type)) { - // The functions strtod() and strtof() accept both 'nan' and - // 'nan(number)' literals. While 'nan(number)' is rejected by the parser - // as an unsupported function if is_tok_ident is true. - if (attribute_.find_last_of(')') != std::string::npos) { - return Error("invalid number: " + attribute_); - } - } - } - // Float numbers or nan, inf, pi, etc. - TRY_ECHECK(kTokenStringOrIdent, IsFloat(in_type), BASE_TYPE_FLOAT); - // An integer constant in string. - TRY_ECHECK(kTokenStringOrIdent, IsInteger(in_type), BASE_TYPE_INT); - // Unknown tokens will be interpreted as string type. - // An attribute value may be a scalar or string constant. - FORCE_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING, - BASE_TYPE_STRING); - } else { - // Try a float number. - TRY_ECHECK(kTokenFloatConstant, IsFloat(in_type), BASE_TYPE_FLOAT); - // Integer token can init any scalar (integer of float). - FORCE_ECHECK(kTokenIntegerConstant, IsScalar(in_type), BASE_TYPE_INT); - } - // Match empty vectors for default-empty-vectors. - if (!match && IsVector(e.type) && token_ == '[') { - NEXT(); - if (token_ != ']') { return Error("Expected `]` in vector default"); } - NEXT(); - match = true; - e.constant = "[]"; - } - -#undef FORCE_ECHECK -#undef TRY_ECHECK -#undef IF_ECHECK_ - - if (!match) { - std::string msg; - msg += "Cannot assign token starting with '" + TokenToStringId(token_) + - "' to value of <" + std::string(kTypeNames[in_type]) + "> type."; - return Error(msg); - } - const auto match_type = e.type.base_type; // may differ from in_type - // The check_now flag must be true when parse a fbs-schema. - // This flag forces to check default scalar values or metadata of field. - // For JSON parser the flag should be false. - // If it is set for JSON each value will be checked twice (see ParseTable). - // Special case 'null' since atot can't handle that. - if (check_now && IsScalar(match_type) && e.constant != "null") { - // clang-format off - switch (match_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: {\ - CTYPE val; \ - ECHECK(atot(e.constant.c_str(), *this, &val)); \ - SingleValueRepack(e, val); \ - break; } - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - default: break; - } - // clang-format on - } - return NoError(); -} - -StructDef *Parser::LookupCreateStruct(const std::string &name, - bool create_if_new, bool definition) { - std::string qualified_name = current_namespace_->GetFullyQualifiedName(name); - // See if it exists pre-declared by an unqualified use. - auto struct_def = LookupStruct(name); - if (struct_def && struct_def->predecl) { - if (definition) { - // Make sure it has the current namespace, and is registered under its - // qualified name. - struct_def->defined_namespace = current_namespace_; - structs_.Move(name, qualified_name); - } - return struct_def; - } - // See if it exists pre-declared by an qualified use. - struct_def = LookupStruct(qualified_name); - if (struct_def && struct_def->predecl) { - if (definition) { - // Make sure it has the current namespace. - struct_def->defined_namespace = current_namespace_; - } - return struct_def; - } - if (!definition && !struct_def) { - struct_def = LookupStructThruParentNamespaces(name); - } - if (!struct_def && create_if_new) { - struct_def = new StructDef(); - if (definition) { - structs_.Add(qualified_name, struct_def); - struct_def->name = name; - struct_def->defined_namespace = current_namespace_; - } else { - // Not a definition. - // Rather than failing, we create a "pre declared" StructDef, due to - // circular references, and check for errors at the end of parsing. - // It is defined in the current namespace, as the best guess what the - // final namespace will be. - structs_.Add(name, struct_def); - struct_def->name = name; - struct_def->defined_namespace = current_namespace_; - struct_def->original_location.reset( - new std::string(file_being_parsed_ + ":" + NumToString(line_))); - } - } - return struct_def; -} - -const EnumVal *EnumDef::MinValue() const { - return vals.vec.empty() ? nullptr : vals.vec.front(); -} -const EnumVal *EnumDef::MaxValue() const { - return vals.vec.empty() ? nullptr : vals.vec.back(); -} - -template<typename T> static uint64_t EnumDistanceImpl(T e1, T e2) { - if (e1 < e2) { std::swap(e1, e2); } // use std for scalars - // Signed overflow may occur, use unsigned calculation. - // The unsigned overflow is well-defined by C++ standard (modulo 2^n). - return static_cast<uint64_t>(e1) - static_cast<uint64_t>(e2); -} - -uint64_t EnumDef::Distance(const EnumVal *v1, const EnumVal *v2) const { - return IsUInt64() ? EnumDistanceImpl(v1->GetAsUInt64(), v2->GetAsUInt64()) - : EnumDistanceImpl(v1->GetAsInt64(), v2->GetAsInt64()); -} - -std::string EnumDef::AllFlags() const { - FLATBUFFERS_ASSERT(attributes.Lookup("bit_flags")); - uint64_t u64 = 0; - for (auto it = Vals().begin(); it != Vals().end(); ++it) { - u64 |= (*it)->GetAsUInt64(); - } - return IsUInt64() ? NumToString(u64) : NumToString(static_cast<int64_t>(u64)); -} - -EnumVal *EnumDef::ReverseLookup(int64_t enum_idx, - bool skip_union_default) const { - auto skip_first = static_cast<int>(is_union && skip_union_default); - for (auto it = Vals().begin() + skip_first; it != Vals().end(); ++it) { - if ((*it)->GetAsInt64() == enum_idx) { return *it; } - } - return nullptr; -} - -EnumVal *EnumDef::FindByValue(const std::string &constant) const { - int64_t i64; - auto done = false; - if (IsUInt64()) { - uint64_t u64; // avoid reinterpret_cast of pointers - done = StringToNumber(constant.c_str(), &u64); - i64 = static_cast<int64_t>(u64); - } else { - done = StringToNumber(constant.c_str(), &i64); - } - FLATBUFFERS_ASSERT(done); - if (!done) return nullptr; - return ReverseLookup(i64, false); -} - -void EnumDef::SortByValue() { - auto &v = vals.vec; - if (IsUInt64()) - std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) { - return e1->GetAsUInt64() < e2->GetAsUInt64(); - }); - else - std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) { - return e1->GetAsInt64() < e2->GetAsInt64(); - }); -} - -void EnumDef::RemoveDuplicates() { - // This method depends form SymbolTable implementation! - // 1) vals.vec - owner (raw pointer) - // 2) vals.dict - access map - auto first = vals.vec.begin(); - auto last = vals.vec.end(); - if (first == last) return; - auto result = first; - while (++first != last) { - if ((*result)->value != (*first)->value) { - *(++result) = *first; - } else { - auto ev = *first; - for (auto it = vals.dict.begin(); it != vals.dict.end(); ++it) { - if (it->second == ev) it->second = *result; // reassign - } - delete ev; // delete enum value - *first = nullptr; - } - } - vals.vec.erase(++result, last); -} - -template<typename T> void EnumDef::ChangeEnumValue(EnumVal *ev, T new_value) { - ev->value = static_cast<int64_t>(new_value); -} - -namespace EnumHelper { -template<BaseType E> struct EnumValType { typedef int64_t type; }; -template<> struct EnumValType<BASE_TYPE_ULONG> { typedef uint64_t type; }; -} // namespace EnumHelper - -struct EnumValBuilder { - EnumVal *CreateEnumerator(const std::string &ev_name) { - FLATBUFFERS_ASSERT(!temp); - auto first = enum_def.vals.vec.empty(); - user_value = first; - temp = new EnumVal(ev_name, first ? 0 : enum_def.vals.vec.back()->value); - return temp; - } - - EnumVal *CreateEnumerator(const std::string &ev_name, int64_t val) { - FLATBUFFERS_ASSERT(!temp); - user_value = true; - temp = new EnumVal(ev_name, val); - return temp; - } - - FLATBUFFERS_CHECKED_ERROR AcceptEnumerator(const std::string &name) { - FLATBUFFERS_ASSERT(temp); - ECHECK(ValidateValue(&temp->value, false == user_value)); - FLATBUFFERS_ASSERT((temp->union_type.enum_def == nullptr) || - (temp->union_type.enum_def == &enum_def)); - auto not_unique = enum_def.vals.Add(name, temp); - temp = nullptr; - if (not_unique) return parser.Error("enum value already exists: " + name); - return NoError(); - } - - FLATBUFFERS_CHECKED_ERROR AcceptEnumerator() { - return AcceptEnumerator(temp->name); - } - - FLATBUFFERS_CHECKED_ERROR AssignEnumeratorValue(const std::string &value) { - user_value = true; - auto fit = false; - if (enum_def.IsUInt64()) { - uint64_t u64; - fit = StringToNumber(value.c_str(), &u64); - temp->value = static_cast<int64_t>(u64); // well-defined since C++20. - } else { - int64_t i64; - fit = StringToNumber(value.c_str(), &i64); - temp->value = i64; - } - if (!fit) return parser.Error("enum value does not fit, \"" + value + "\""); - return NoError(); - } - - template<BaseType E, typename CTYPE> - inline FLATBUFFERS_CHECKED_ERROR ValidateImpl(int64_t *ev, int m) { - typedef typename EnumHelper::EnumValType<E>::type T; // int64_t or uint64_t - static_assert(sizeof(T) == sizeof(int64_t), "invalid EnumValType"); - const auto v = static_cast<T>(*ev); - auto up = static_cast<T>((flatbuffers::numeric_limits<CTYPE>::max)()); - auto dn = static_cast<T>((flatbuffers::numeric_limits<CTYPE>::lowest)()); - if (v < dn || v > (up - m)) { - return parser.Error("enum value does not fit, \"" + NumToString(v) + - (m ? " + 1\"" : "\"") + " out of " + - TypeToIntervalString<CTYPE>()); - } - *ev = static_cast<int64_t>(v + m); // well-defined since C++20. - return NoError(); - } - - FLATBUFFERS_CHECKED_ERROR ValidateValue(int64_t *ev, bool next) { - // clang-format off - switch (enum_def.underlying_type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_##ENUM: { \ - if (!IsInteger(BASE_TYPE_##ENUM)) break; \ - return ValidateImpl<BASE_TYPE_##ENUM, CTYPE>(ev, next ? 1 : 0); \ - } - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - default: break; - } - // clang-format on - return parser.Error("fatal: invalid enum underlying type"); - } - - EnumValBuilder(Parser &_parser, EnumDef &_enum_def) - : parser(_parser), - enum_def(_enum_def), - temp(nullptr), - user_value(false) {} - - ~EnumValBuilder() { delete temp; } - - Parser &parser; - EnumDef &enum_def; - EnumVal *temp; - bool user_value; -}; - -CheckedError Parser::ParseEnum(const bool is_union, EnumDef **dest) { - std::vector<std::string> enum_comment = doc_comment_; - NEXT(); - std::string enum_name = attribute_; - EXPECT(kTokenIdentifier); - EnumDef *enum_def; - ECHECK(StartEnum(enum_name, is_union, &enum_def)); - enum_def->doc_comment = enum_comment; - if (!is_union && !opts.proto_mode) { - // Give specialized error message, since this type spec used to - // be optional in the first FlatBuffers release. - if (!Is(':')) { - return Error( - "must specify the underlying integer type for this" - " enum (e.g. \': short\', which was the default)."); - } else { - NEXT(); - } - // Specify the integer type underlying this enum. - ECHECK(ParseType(enum_def->underlying_type)); - if (!IsInteger(enum_def->underlying_type.base_type) || - IsBool(enum_def->underlying_type.base_type)) - return Error("underlying enum type must be integral"); - // Make this type refer back to the enum it was derived from. - enum_def->underlying_type.enum_def = enum_def; - } - ECHECK(ParseMetaData(&enum_def->attributes)); - const auto underlying_type = enum_def->underlying_type.base_type; - if (enum_def->attributes.Lookup("bit_flags") && - !IsUnsigned(underlying_type)) { - // todo: Convert to the Error in the future? - Warning("underlying type of bit_flags enum must be unsigned"); - } - EnumValBuilder evb(*this, *enum_def); - EXPECT('{'); - // A lot of code generatos expect that an enum is not-empty. - if ((is_union || Is('}')) && !opts.proto_mode) { - evb.CreateEnumerator("NONE"); - ECHECK(evb.AcceptEnumerator()); - } - std::set<std::pair<BaseType, StructDef *>> union_types; - while (!Is('}')) { - if (opts.proto_mode && attribute_ == "option") { - ECHECK(ParseProtoOption()); - } else { - auto &ev = *evb.CreateEnumerator(attribute_); - auto full_name = ev.name; - ev.doc_comment = doc_comment_; - EXPECT(kTokenIdentifier); - if (is_union) { - ECHECK(ParseNamespacing(&full_name, &ev.name)); - if (opts.union_value_namespacing) { - // Since we can't namespace the actual enum identifiers, turn - // namespace parts into part of the identifier. - ev.name = full_name; - std::replace(ev.name.begin(), ev.name.end(), '.', '_'); - } - if (Is(':')) { - NEXT(); - ECHECK(ParseType(ev.union_type)); - if (ev.union_type.base_type != BASE_TYPE_STRUCT && - ev.union_type.base_type != BASE_TYPE_STRING) - return Error("union value type may only be table/struct/string"); - } else { - ev.union_type = Type(BASE_TYPE_STRUCT, LookupCreateStruct(full_name)); - } - if (!enum_def->uses_multiple_type_instances) { - auto ins = union_types.insert(std::make_pair( - ev.union_type.base_type, ev.union_type.struct_def)); - enum_def->uses_multiple_type_instances = (false == ins.second); - } - } - - if (Is('=')) { - NEXT(); - ECHECK(evb.AssignEnumeratorValue(attribute_)); - EXPECT(kTokenIntegerConstant); - } - - ECHECK(evb.AcceptEnumerator()); - - if (opts.proto_mode && Is('[')) { - NEXT(); - // ignore attributes on enums. - while (token_ != ']') NEXT(); - NEXT(); - } - } - if (!Is(opts.proto_mode ? ';' : ',')) break; - NEXT(); - } - EXPECT('}'); - - // At this point, the enum can be empty if input is invalid proto-file. - if (!enum_def->size()) - return Error("incomplete enum declaration, values not found"); - - if (enum_def->attributes.Lookup("bit_flags")) { - const auto base_width = static_cast<uint64_t>(8 * SizeOf(underlying_type)); - for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end(); - ++it) { - auto ev = *it; - const auto u = ev->GetAsUInt64(); - // Stop manipulations with the sign. - if (!IsUnsigned(underlying_type) && u == (base_width - 1)) - return Error("underlying type of bit_flags enum must be unsigned"); - if (u >= base_width) - return Error("bit flag out of range of underlying integral type"); - enum_def->ChangeEnumValue(ev, 1ULL << u); - } - } - - enum_def->SortByValue(); // Must be sorted to use MinValue/MaxValue. - - // Ensure enum value uniqueness. - auto prev_it = enum_def->Vals().begin(); - for (auto it = prev_it + 1; it != enum_def->Vals().end(); ++it) { - auto prev_ev = *prev_it; - auto ev = *it; - if (prev_ev->GetAsUInt64() == ev->GetAsUInt64()) - return Error("all enum values must be unique: " + prev_ev->name + - " and " + ev->name + " are both " + - NumToString(ev->GetAsInt64())); - } - - if (dest) *dest = enum_def; - types_.Add(current_namespace_->GetFullyQualifiedName(enum_def->name), - new Type(BASE_TYPE_UNION, nullptr, enum_def)); - return NoError(); -} - -CheckedError Parser::StartStruct(const std::string &name, StructDef **dest) { - auto &struct_def = *LookupCreateStruct(name, true, true); - if (!struct_def.predecl) return Error("datatype already exists: " + name); - struct_def.predecl = false; - struct_def.name = name; - struct_def.file = file_being_parsed_; - // Move this struct to the back of the vector just in case it was predeclared, - // to preserve declaration order. - *std::remove(structs_.vec.begin(), structs_.vec.end(), &struct_def) = - &struct_def; - *dest = &struct_def; - return NoError(); -} - -CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields, - StructDef *struct_def, const char *suffix, - BaseType basetype) { - auto len = strlen(suffix); - for (auto it = fields.begin(); it != fields.end(); ++it) { - auto &fname = (*it)->name; - if (fname.length() > len && - fname.compare(fname.length() - len, len, suffix) == 0 && - (*it)->value.type.base_type != BASE_TYPE_UTYPE) { - auto field = - struct_def->fields.Lookup(fname.substr(0, fname.length() - len)); - if (field && field->value.type.base_type == basetype) - return Error("Field " + fname + - " would clash with generated functions for field " + - field->name); - } - } - return NoError(); -} - -bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions &opts) { - static FLATBUFFERS_CONSTEXPR unsigned long supported_langs = - IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster | - IDLOptions::kKotlin | IDLOptions::kCpp | IDLOptions::kJava | - IDLOptions::kCSharp | IDLOptions::kTs | IDLOptions::kBinary; - unsigned long langs = opts.lang_to_generate; - return (langs > 0 && langs < IDLOptions::kMAX) && !(langs & ~supported_langs); -} -bool Parser::SupportsOptionalScalars() const { - // Check in general if a language isn't specified. - return opts.lang_to_generate == 0 || SupportsOptionalScalars(opts); -} - -bool Parser::SupportsDefaultVectorsAndStrings() const { - static FLATBUFFERS_CONSTEXPR unsigned long supported_langs = - IDLOptions::kRust | IDLOptions::kSwift; - return !(opts.lang_to_generate & ~supported_langs); -} - -bool Parser::SupportsAdvancedUnionFeatures() const { - return opts.lang_to_generate != 0 && - (opts.lang_to_generate & - ~(IDLOptions::kCpp | IDLOptions::kTs | IDLOptions::kPhp | - IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kKotlin | - IDLOptions::kBinary | IDLOptions::kSwift)) == 0; -} - -bool Parser::SupportsAdvancedArrayFeatures() const { - return (opts.lang_to_generate & - ~(IDLOptions::kCpp | IDLOptions::kPython | IDLOptions::kJava | - IDLOptions::kCSharp | IDLOptions::kJsonSchema | IDLOptions::kJson | - IDLOptions::kBinary | IDLOptions::kRust)) == 0; -} - -Namespace *Parser::UniqueNamespace(Namespace *ns) { - for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) { - if (ns->components == (*it)->components) { - delete ns; - return *it; - } - } - namespaces_.push_back(ns); - return ns; -} - -std::string Parser::UnqualifiedName(const std::string &full_qualified_name) { - Namespace *ns = new Namespace(); - - std::size_t current, previous = 0; - current = full_qualified_name.find('.'); - while (current != std::string::npos) { - ns->components.push_back( - full_qualified_name.substr(previous, current - previous)); - previous = current + 1; - current = full_qualified_name.find('.', previous); - } - current_namespace_ = UniqueNamespace(ns); - return full_qualified_name.substr(previous, current - previous); -} - -static bool compareFieldDefs(const FieldDef *a, const FieldDef *b) { - auto a_id = atoi(a->attributes.Lookup("id")->constant.c_str()); - auto b_id = atoi(b->attributes.Lookup("id")->constant.c_str()); - return a_id < b_id; -} - -CheckedError Parser::ParseDecl() { - std::vector<std::string> dc = doc_comment_; - bool fixed = IsIdent("struct"); - if (!fixed && !IsIdent("table")) return Error("declaration expected"); - NEXT(); - std::string name = attribute_; - EXPECT(kTokenIdentifier); - StructDef *struct_def; - ECHECK(StartStruct(name, &struct_def)); - struct_def->doc_comment = dc; - struct_def->fixed = fixed; - ECHECK(ParseMetaData(&struct_def->attributes)); - struct_def->sortbysize = - struct_def->attributes.Lookup("original_order") == nullptr && !fixed; - EXPECT('{'); - while (token_ != '}') ECHECK(ParseField(*struct_def)); - if (fixed) { - const auto force_align = struct_def->attributes.Lookup("force_align"); - if (force_align) { - size_t align; - ECHECK(ParseAlignAttribute(force_align->constant, struct_def->minalign, - &align)); - struct_def->minalign = align; - } - if (!struct_def->bytesize) return Error("size 0 structs not allowed"); - } - struct_def->PadLastField(struct_def->minalign); - // Check if this is a table that has manual id assignments - auto &fields = struct_def->fields.vec; - if (!fixed && fields.size()) { - size_t num_id_fields = 0; - for (auto it = fields.begin(); it != fields.end(); ++it) { - if ((*it)->attributes.Lookup("id")) num_id_fields++; - } - // If any fields have ids.. - if (num_id_fields || opts.require_explicit_ids) { - // Then all fields must have them. - if (num_id_fields != fields.size()) { - if (opts.require_explicit_ids) { - return Error( - "all fields must have an 'id' attribute when " - "--require-explicit-ids is used"); - } else { - return Error( - "either all fields or no fields must have an 'id' attribute"); - } - } - // Simply sort by id, then the fields are the same as if no ids had - // been specified. - std::sort(fields.begin(), fields.end(), compareFieldDefs); - // Verify we have a contiguous set, and reassign vtable offsets. - FLATBUFFERS_ASSERT(fields.size() <= - flatbuffers::numeric_limits<voffset_t>::max()); - for (voffset_t i = 0; i < static_cast<voffset_t>(fields.size()); i++) { - auto &field = *fields[i]; - const auto &id_str = field.attributes.Lookup("id")->constant; - // Metadata values have a dynamic type, they can be `float`, 'int', or - // 'string`. - // The FieldIndexToOffset(i) expects the voffset_t so `id` is limited by - // this type. - voffset_t id = 0; - const auto done = !atot(id_str.c_str(), *this, &id).Check(); - if (!done) - return Error("field id\'s must be non-negative number, field: " + - field.name + ", id: " + id_str); - if (i != id) - return Error("field id\'s must be consecutive from 0, id " + - NumToString(i) + " missing or set twice, field: " + - field.name + ", id: " + id_str); - field.value.offset = FieldIndexToOffset(i); - } - } - } - - ECHECK( - CheckClash(fields, struct_def, UnionTypeFieldSuffix(), BASE_TYPE_UNION)); - ECHECK(CheckClash(fields, struct_def, "Type", BASE_TYPE_UNION)); - ECHECK(CheckClash(fields, struct_def, "_length", BASE_TYPE_VECTOR)); - ECHECK(CheckClash(fields, struct_def, "Length", BASE_TYPE_VECTOR)); - ECHECK(CheckClash(fields, struct_def, "_byte_vector", BASE_TYPE_STRING)); - ECHECK(CheckClash(fields, struct_def, "ByteVector", BASE_TYPE_STRING)); - EXPECT('}'); - types_.Add(current_namespace_->GetFullyQualifiedName(struct_def->name), - new Type(BASE_TYPE_STRUCT, struct_def, nullptr)); - return NoError(); -} - -CheckedError Parser::ParseService() { - std::vector<std::string> service_comment = doc_comment_; - NEXT(); - auto service_name = attribute_; - EXPECT(kTokenIdentifier); - auto &service_def = *new ServiceDef(); - service_def.name = service_name; - service_def.file = file_being_parsed_; - service_def.doc_comment = service_comment; - service_def.defined_namespace = current_namespace_; - if (services_.Add(current_namespace_->GetFullyQualifiedName(service_name), - &service_def)) - return Error("service already exists: " + service_name); - ECHECK(ParseMetaData(&service_def.attributes)); - EXPECT('{'); - do { - std::vector<std::string> doc_comment = doc_comment_; - auto rpc_name = attribute_; - EXPECT(kTokenIdentifier); - EXPECT('('); - Type reqtype, resptype; - ECHECK(ParseTypeIdent(reqtype)); - EXPECT(')'); - EXPECT(':'); - ECHECK(ParseTypeIdent(resptype)); - if (reqtype.base_type != BASE_TYPE_STRUCT || reqtype.struct_def->fixed || - resptype.base_type != BASE_TYPE_STRUCT || resptype.struct_def->fixed) - return Error("rpc request and response types must be tables"); - auto &rpc = *new RPCCall(); - rpc.name = rpc_name; - rpc.request = reqtype.struct_def; - rpc.response = resptype.struct_def; - rpc.doc_comment = doc_comment; - if (service_def.calls.Add(rpc_name, &rpc)) - return Error("rpc already exists: " + rpc_name); - ECHECK(ParseMetaData(&rpc.attributes)); - EXPECT(';'); - } while (token_ != '}'); - NEXT(); - return NoError(); -} - -bool Parser::SetRootType(const char *name) { - root_struct_def_ = LookupStruct(name); - if (!root_struct_def_) - root_struct_def_ = - LookupStruct(current_namespace_->GetFullyQualifiedName(name)); - return root_struct_def_ != nullptr; -} - -void Parser::MarkGenerated() { - // This function marks all existing definitions as having already - // been generated, which signals no code for included files should be - // generated. - for (auto it = enums_.vec.begin(); it != enums_.vec.end(); ++it) { - (*it)->generated = true; - } - for (auto it = structs_.vec.begin(); it != structs_.vec.end(); ++it) { - if (!(*it)->predecl) { (*it)->generated = true; } - } - for (auto it = services_.vec.begin(); it != services_.vec.end(); ++it) { - (*it)->generated = true; - } -} - -CheckedError Parser::ParseNamespace() { - NEXT(); - auto ns = new Namespace(); - namespaces_.push_back(ns); // Store it here to not leak upon error. - if (token_ != ';') { - for (;;) { - ns->components.push_back(attribute_); - EXPECT(kTokenIdentifier); - if (Is('.')) NEXT() else break; - } - } - namespaces_.pop_back(); - current_namespace_ = UniqueNamespace(ns); - EXPECT(';'); - return NoError(); -} - -// Best effort parsing of .proto declarations, with the aim to turn them -// in the closest corresponding FlatBuffer equivalent. -// We parse everything as identifiers instead of keywords, since we don't -// want protobuf keywords to become invalid identifiers in FlatBuffers. -CheckedError Parser::ParseProtoDecl() { - bool isextend = IsIdent("extend"); - if (IsIdent("package")) { - // These are identical in syntax to FlatBuffer's namespace decl. - ECHECK(ParseNamespace()); - } else if (IsIdent("message") || isextend) { - std::vector<std::string> struct_comment = doc_comment_; - NEXT(); - StructDef *struct_def = nullptr; - Namespace *parent_namespace = nullptr; - if (isextend) { - if (Is('.')) NEXT(); // qualified names may start with a . ? - auto id = attribute_; - EXPECT(kTokenIdentifier); - ECHECK(ParseNamespacing(&id, nullptr)); - struct_def = LookupCreateStruct(id, false); - if (!struct_def) - return Error("cannot extend unknown message type: " + id); - } else { - std::string name = attribute_; - EXPECT(kTokenIdentifier); - ECHECK(StartStruct(name, &struct_def)); - // Since message definitions can be nested, we create a new namespace. - auto ns = new Namespace(); - // Copy of current namespace. - *ns = *current_namespace_; - // But with current message name. - ns->components.push_back(name); - ns->from_table++; - parent_namespace = current_namespace_; - current_namespace_ = UniqueNamespace(ns); - } - struct_def->doc_comment = struct_comment; - ECHECK(ParseProtoFields(struct_def, isextend, false)); - if (!isextend) { current_namespace_ = parent_namespace; } - if (Is(';')) NEXT(); - } else if (IsIdent("enum")) { - // These are almost the same, just with different terminator: - EnumDef *enum_def; - ECHECK(ParseEnum(false, &enum_def)); - if (Is(';')) NEXT(); - // Temp: remove any duplicates, as .fbs files can't handle them. - enum_def->RemoveDuplicates(); - } else if (IsIdent("syntax")) { // Skip these. - NEXT(); - EXPECT('='); - EXPECT(kTokenStringConstant); - EXPECT(';'); - } else if (IsIdent("option")) { // Skip these. - ECHECK(ParseProtoOption()); - EXPECT(';'); - } else if (IsIdent("service")) { // Skip these. - NEXT(); - EXPECT(kTokenIdentifier); - ECHECK(ParseProtoCurliesOrIdent()); - } else { - return Error("don\'t know how to parse .proto declaration starting with " + - TokenToStringId(token_)); - } - return NoError(); -} - -CheckedError Parser::StartEnum(const std::string &enum_name, bool is_union, - EnumDef **dest) { - auto &enum_def = *new EnumDef(); - enum_def.name = enum_name; - enum_def.file = file_being_parsed_; - enum_def.doc_comment = doc_comment_; - enum_def.is_union = is_union; - enum_def.defined_namespace = current_namespace_; - if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name), - &enum_def)) - return Error("enum already exists: " + enum_name); - enum_def.underlying_type.base_type = - is_union ? BASE_TYPE_UTYPE : BASE_TYPE_INT; - enum_def.underlying_type.enum_def = &enum_def; - if (dest) *dest = &enum_def; - return NoError(); -} - -CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend, - bool inside_oneof) { - EXPECT('{'); - while (token_ != '}') { - if (IsIdent("message") || IsIdent("extend") || IsIdent("enum")) { - // Nested declarations. - ECHECK(ParseProtoDecl()); - } else if (IsIdent("extensions")) { // Skip these. - NEXT(); - EXPECT(kTokenIntegerConstant); - if (Is(kTokenIdentifier)) { - NEXT(); // to - NEXT(); // num - } - EXPECT(';'); - } else if (IsIdent("option")) { // Skip these. - ECHECK(ParseProtoOption()); - EXPECT(';'); - } else if (IsIdent("reserved")) { // Skip these. - NEXT(); - while (!Is(';')) { NEXT(); } // A variety of formats, just skip. - NEXT(); - } else { - std::vector<std::string> field_comment = doc_comment_; - // Parse the qualifier. - bool required = false; - bool repeated = false; - bool oneof = false; - if (!inside_oneof) { - if (IsIdent("optional")) { - // This is the default. - NEXT(); - } else if (IsIdent("required")) { - required = true; - NEXT(); - } else if (IsIdent("repeated")) { - repeated = true; - NEXT(); - } else if (IsIdent("oneof")) { - oneof = true; - NEXT(); - } else { - // can't error, proto3 allows decls without any of the above. - } - } - StructDef *anonymous_struct = nullptr; - EnumDef *oneof_union = nullptr; - Type type; - if (IsIdent("group") || oneof) { - if (!oneof) NEXT(); - if (oneof && opts.proto_oneof_union) { - auto name = MakeCamel(attribute_, true) + "Union"; - ECHECK(StartEnum(name, true, &oneof_union)); - type = Type(BASE_TYPE_UNION, nullptr, oneof_union); - } else { - auto name = "Anonymous" + NumToString(anonymous_counter_++); - ECHECK(StartStruct(name, &anonymous_struct)); - type = Type(BASE_TYPE_STRUCT, anonymous_struct); - } - } else { - ECHECK(ParseTypeFromProtoType(&type)); - } - // Repeated elements get mapped to a vector. - if (repeated) { - type.element = type.base_type; - type.base_type = BASE_TYPE_VECTOR; - if (type.element == BASE_TYPE_VECTOR) { - // We have a vector or vectors, which FlatBuffers doesn't support. - // For now make it a vector of string (since the source is likely - // "repeated bytes"). - // TODO(wvo): A better solution would be to wrap this in a table. - type.element = BASE_TYPE_STRING; - } - } - std::string name = attribute_; - EXPECT(kTokenIdentifier); - if (!oneof) { - // Parse the field id. Since we're just translating schemas, not - // any kind of binary compatibility, we can safely ignore these, and - // assign our own. - EXPECT('='); - EXPECT(kTokenIntegerConstant); - } - FieldDef *field = nullptr; - if (isextend) { - // We allow a field to be re-defined when extending. - // TODO: are there situations where that is problematic? - field = struct_def->fields.Lookup(name); - } - if (!field) ECHECK(AddField(*struct_def, name, type, &field)); - field->doc_comment = field_comment; - if (!IsScalar(type.base_type) && required) { - field->presence = FieldDef::kRequired; - } - // See if there's a default specified. - if (Is('[')) { - NEXT(); - for (;;) { - auto key = attribute_; - ECHECK(ParseProtoKey()); - EXPECT('='); - auto val = attribute_; - ECHECK(ParseProtoCurliesOrIdent()); - if (key == "default") { - // Temp: skip non-numeric and non-boolean defaults (enums). - auto numeric = strpbrk(val.c_str(), "0123456789-+."); - if (IsScalar(type.base_type) && numeric == val.c_str()) { - field->value.constant = val; - } else if (val == "true") { - field->value.constant = val; - } // "false" is default, no need to handle explicitly. - } else if (key == "deprecated") { - field->deprecated = val == "true"; - } - if (!Is(',')) break; - NEXT(); - } - EXPECT(']'); - } - if (anonymous_struct) { - ECHECK(ParseProtoFields(anonymous_struct, false, oneof)); - if (Is(';')) NEXT(); - } else if (oneof_union) { - // Parse into a temporary StructDef, then transfer fields into an - // EnumDef describing the oneof as a union. - StructDef oneof_struct; - ECHECK(ParseProtoFields(&oneof_struct, false, oneof)); - if (Is(';')) NEXT(); - for (auto field_it = oneof_struct.fields.vec.begin(); - field_it != oneof_struct.fields.vec.end(); ++field_it) { - const auto &oneof_field = **field_it; - const auto &oneof_type = oneof_field.value.type; - if (oneof_type.base_type != BASE_TYPE_STRUCT || - !oneof_type.struct_def || oneof_type.struct_def->fixed) - return Error("oneof '" + name + - "' cannot be mapped to a union because member '" + - oneof_field.name + "' is not a table type."); - EnumValBuilder evb(*this, *oneof_union); - auto ev = evb.CreateEnumerator(oneof_type.struct_def->name); - ev->union_type = oneof_type; - ev->doc_comment = oneof_field.doc_comment; - ECHECK(evb.AcceptEnumerator(oneof_field.name)); - } - } else { - EXPECT(';'); - } - } - } - NEXT(); - return NoError(); -} - -CheckedError Parser::ParseProtoKey() { - if (token_ == '(') { - NEXT(); - // Skip "(a.b)" style custom attributes. - while (token_ == '.' || token_ == kTokenIdentifier) NEXT(); - EXPECT(')'); - while (Is('.')) { - NEXT(); - EXPECT(kTokenIdentifier); - } - } else { - EXPECT(kTokenIdentifier); - } - return NoError(); -} - -CheckedError Parser::ParseProtoCurliesOrIdent() { - if (Is('{')) { - NEXT(); - for (int nesting = 1; nesting;) { - if (token_ == '{') - nesting++; - else if (token_ == '}') - nesting--; - NEXT(); - } - } else { - NEXT(); // Any single token. - } - return NoError(); -} - -CheckedError Parser::ParseProtoOption() { - NEXT(); - ECHECK(ParseProtoKey()); - EXPECT('='); - ECHECK(ParseProtoCurliesOrIdent()); - return NoError(); -} - -// Parse a protobuf type, and map it to the corresponding FlatBuffer one. -CheckedError Parser::ParseTypeFromProtoType(Type *type) { - struct type_lookup { - const char *proto_type; - BaseType fb_type, element; - }; - static type_lookup lookup[] = { - { "float", BASE_TYPE_FLOAT, BASE_TYPE_NONE }, - { "double", BASE_TYPE_DOUBLE, BASE_TYPE_NONE }, - { "int32", BASE_TYPE_INT, BASE_TYPE_NONE }, - { "int64", BASE_TYPE_LONG, BASE_TYPE_NONE }, - { "uint32", BASE_TYPE_UINT, BASE_TYPE_NONE }, - { "uint64", BASE_TYPE_ULONG, BASE_TYPE_NONE }, - { "sint32", BASE_TYPE_INT, BASE_TYPE_NONE }, - { "sint64", BASE_TYPE_LONG, BASE_TYPE_NONE }, - { "fixed32", BASE_TYPE_UINT, BASE_TYPE_NONE }, - { "fixed64", BASE_TYPE_ULONG, BASE_TYPE_NONE }, - { "sfixed32", BASE_TYPE_INT, BASE_TYPE_NONE }, - { "sfixed64", BASE_TYPE_LONG, BASE_TYPE_NONE }, - { "bool", BASE_TYPE_BOOL, BASE_TYPE_NONE }, - { "string", BASE_TYPE_STRING, BASE_TYPE_NONE }, - { "bytes", BASE_TYPE_VECTOR, BASE_TYPE_UCHAR }, - { nullptr, BASE_TYPE_NONE, BASE_TYPE_NONE } - }; - for (auto tl = lookup; tl->proto_type; tl++) { - if (attribute_ == tl->proto_type) { - type->base_type = tl->fb_type; - type->element = tl->element; - NEXT(); - return NoError(); - } - } - if (Is('.')) NEXT(); // qualified names may start with a . ? - ECHECK(ParseTypeIdent(*type)); - return NoError(); -} - -CheckedError Parser::SkipAnyJsonValue() { - ParseDepthGuard depth_guard(this); - ECHECK(depth_guard.Check()); - - switch (token_) { - case '{': { - size_t fieldn_outer = 0; - return ParseTableDelimiters(fieldn_outer, nullptr, - [&](const std::string &, size_t &fieldn, - const StructDef *) -> CheckedError { - ECHECK(SkipAnyJsonValue()); - fieldn++; - return NoError(); - }); - } - case '[': { - uoffset_t count = 0; - return ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError { - return SkipAnyJsonValue(); - }); - } - case kTokenStringConstant: - case kTokenIntegerConstant: - case kTokenFloatConstant: NEXT(); break; - default: - if (IsIdent("true") || IsIdent("false") || IsIdent("null")) { - NEXT(); - } else - return TokenError(); - } - return NoError(); -} - -CheckedError Parser::ParseFlexBufferNumericConstant( - flexbuffers::Builder *builder) { - double d; - if (!StringToNumber(attribute_.c_str(), &d)) - return Error("unexpected floating-point constant: " + attribute_); - builder->Double(d); - return NoError(); -} - -CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) { - ParseDepthGuard depth_guard(this); - ECHECK(depth_guard.Check()); - - switch (token_) { - case '{': { - auto start = builder->StartMap(); - size_t fieldn_outer = 0; - auto err = - ParseTableDelimiters(fieldn_outer, nullptr, - [&](const std::string &name, size_t &fieldn, - const StructDef *) -> CheckedError { - builder->Key(name); - ECHECK(ParseFlexBufferValue(builder)); - fieldn++; - return NoError(); - }); - ECHECK(err); - builder->EndMap(start); - if (builder->HasDuplicateKeys()) - return Error("FlexBuffers map has duplicate keys"); - break; - } - case '[': { - auto start = builder->StartVector(); - uoffset_t count = 0; - ECHECK(ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError { - return ParseFlexBufferValue(builder); - })); - builder->EndVector(start, false, false); - break; - } - case kTokenStringConstant: - builder->String(attribute_); - EXPECT(kTokenStringConstant); - break; - case kTokenIntegerConstant: - builder->Int(StringToInt(attribute_.c_str())); - EXPECT(kTokenIntegerConstant); - break; - case kTokenFloatConstant: { - double d; - StringToNumber(attribute_.c_str(), &d); - builder->Double(d); - EXPECT(kTokenFloatConstant); - break; - } - case '-': - case '+': { - // `[-+]?(nan|inf|infinity)`, see ParseSingleValue(). - const auto sign = static_cast<char>(token_); - NEXT(); - if (token_ != kTokenIdentifier) - return Error("floating-point constant expected"); - attribute_.insert(size_t(0), size_t(1), sign); - ECHECK(ParseFlexBufferNumericConstant(builder)); - NEXT(); - break; - } - default: - if (IsIdent("true")) { - builder->Bool(true); - NEXT(); - } else if (IsIdent("false")) { - builder->Bool(false); - NEXT(); - } else if (IsIdent("null")) { - builder->Null(); - NEXT(); - } else if (IsIdent("inf") || IsIdent("infinity") || IsIdent("nan")) { - ECHECK(ParseFlexBufferNumericConstant(builder)); - NEXT(); - } else - return TokenError(); - } - return NoError(); -} - -bool Parser::ParseFlexBuffer(const char *source, const char *source_filename, - flexbuffers::Builder *builder) { - const auto initial_depth = parse_depth_counter_; - (void)initial_depth; - auto ok = !StartParseFile(source, source_filename).Check() && - !ParseFlexBufferValue(builder).Check(); - if (ok) builder->Finish(); - FLATBUFFERS_ASSERT(initial_depth == parse_depth_counter_); - return ok; -} - -bool Parser::Parse(const char *source, const char **include_paths, - const char *source_filename) { - const auto initial_depth = parse_depth_counter_; - (void)initial_depth; - bool r; - - if (opts.use_flexbuffers) { - r = ParseFlexBuffer(source, source_filename, &flex_builder_); - } else { - r = !ParseRoot(source, include_paths, source_filename).Check(); - } - FLATBUFFERS_ASSERT(initial_depth == parse_depth_counter_); - return r; -} - -bool Parser::ParseJson(const char *json, const char *json_filename) { - const auto initial_depth = parse_depth_counter_; - (void)initial_depth; - builder_.Clear(); - const auto done = - !StartParseFile(json, json_filename).Check() && !DoParseJson().Check(); - FLATBUFFERS_ASSERT(initial_depth == parse_depth_counter_); - return done; -} - -CheckedError Parser::StartParseFile(const char *source, - const char *source_filename) { - file_being_parsed_ = source_filename ? source_filename : ""; - source_ = source; - ResetState(source_); - error_.clear(); - ECHECK(SkipByteOrderMark()); - NEXT(); - if (Is(kTokenEof)) return Error("input file is empty"); - return NoError(); -} - -CheckedError Parser::ParseRoot(const char *source, const char **include_paths, - const char *source_filename) { - ECHECK(DoParse(source, include_paths, source_filename, nullptr)); - - // Check that all types were defined. - for (auto it = structs_.vec.begin(); it != structs_.vec.end();) { - auto &struct_def = **it; - if (struct_def.predecl) { - if (opts.proto_mode) { - // Protos allow enums to be used before declaration, so check if that - // is the case here. - EnumDef *enum_def = nullptr; - for (size_t components = - struct_def.defined_namespace->components.size() + 1; - components && !enum_def; components--) { - auto qualified_name = - struct_def.defined_namespace->GetFullyQualifiedName( - struct_def.name, components - 1); - enum_def = LookupEnum(qualified_name); - } - if (enum_def) { - // This is pretty slow, but a simple solution for now. - auto initial_count = struct_def.refcount; - for (auto struct_it = structs_.vec.begin(); - struct_it != structs_.vec.end(); ++struct_it) { - auto &sd = **struct_it; - for (auto field_it = sd.fields.vec.begin(); - field_it != sd.fields.vec.end(); ++field_it) { - auto &field = **field_it; - if (field.value.type.struct_def == &struct_def) { - field.value.type.struct_def = nullptr; - field.value.type.enum_def = enum_def; - auto &bt = IsVector(field.value.type) - ? field.value.type.element - : field.value.type.base_type; - FLATBUFFERS_ASSERT(bt == BASE_TYPE_STRUCT); - bt = enum_def->underlying_type.base_type; - struct_def.refcount--; - enum_def->refcount++; - } - } - } - if (struct_def.refcount) - return Error("internal: " + NumToString(struct_def.refcount) + "/" + - NumToString(initial_count) + - " use(s) of pre-declaration enum not accounted for: " + - enum_def->name); - structs_.dict.erase(structs_.dict.find(struct_def.name)); - it = structs_.vec.erase(it); - delete &struct_def; - continue; // Skip error. - } - } - auto err = "type referenced but not defined (check namespace): " + - struct_def.name; - if (struct_def.original_location) - err += ", originally at: " + *struct_def.original_location; - return Error(err); - } - ++it; - } - - // This check has to happen here and not earlier, because only now do we - // know for sure what the type of these are. - for (auto it = enums_.vec.begin(); it != enums_.vec.end(); ++it) { - auto &enum_def = **it; - if (enum_def.is_union) { - for (auto val_it = enum_def.Vals().begin(); - val_it != enum_def.Vals().end(); ++val_it) { - auto &val = **val_it; - if (!SupportsAdvancedUnionFeatures() && - (IsStruct(val.union_type) || IsString(val.union_type))) - return Error( - "only tables can be union elements in the generated language: " + - val.name); - } - } - } - // Parse JSON object only if the scheme has been parsed. - if (token_ == '{') { ECHECK(DoParseJson()); } - EXPECT(kTokenEof); - return NoError(); -} - -// Generate a unique hash for a file based on its name and contents (if any). -static uint64_t HashFile(const char *source_filename, const char *source) { - uint64_t hash = 0; - - if (source_filename) - hash = HashFnv1a<uint64_t>(StripPath(source_filename).c_str()); - - if (source && *source) hash ^= HashFnv1a<uint64_t>(source); - - return hash; -} - -CheckedError Parser::DoParse(const char *source, const char **include_paths, - const char *source_filename, - const char *include_filename) { - uint64_t source_hash = 0; - if (source_filename) { - // If the file is in-memory, don't include its contents in the hash as we - // won't be able to load them later. - if (FileExists(source_filename)) - source_hash = HashFile(source_filename, source); - else - source_hash = HashFile(source_filename, nullptr); - - if (included_files_.find(source_hash) == included_files_.end()) { - included_files_[source_hash] = include_filename ? include_filename : ""; - files_included_per_file_[source_filename] = std::set<std::string>(); - } else { - return NoError(); - } - } - if (!include_paths) { - static const char *current_directory[] = { "", nullptr }; - include_paths = current_directory; - } - field_stack_.clear(); - builder_.Clear(); - // Start with a blank namespace just in case this file doesn't have one. - current_namespace_ = empty_namespace_; - - ECHECK(StartParseFile(source, source_filename)); - - // Includes must come before type declarations: - for (;;) { - // Parse pre-include proto statements if any: - if (opts.proto_mode && (attribute_ == "option" || attribute_ == "syntax" || - attribute_ == "package")) { - ECHECK(ParseProtoDecl()); - } else if (IsIdent("native_include")) { - NEXT(); - vector_emplace_back(&native_included_files_, attribute_); - EXPECT(kTokenStringConstant); - EXPECT(';'); - } else if (IsIdent("include") || (opts.proto_mode && IsIdent("import"))) { - NEXT(); - if (opts.proto_mode && attribute_ == "public") NEXT(); - auto name = flatbuffers::PosixPath(attribute_.c_str()); - EXPECT(kTokenStringConstant); - // Look for the file relative to the directory of the current file. - std::string filepath; - if (source_filename) { - auto source_file_directory = - flatbuffers::StripFileName(source_filename); - filepath = flatbuffers::ConCatPathFileName(source_file_directory, name); - } - if (filepath.empty() || !FileExists(filepath.c_str())) { - // Look for the file in include_paths. - for (auto paths = include_paths; paths && *paths; paths++) { - filepath = flatbuffers::ConCatPathFileName(*paths, name); - if (FileExists(filepath.c_str())) break; - } - } - if (filepath.empty()) - return Error("unable to locate include file: " + name); - if (source_filename) - files_included_per_file_[source_filename].insert(filepath); - - std::string contents; - bool file_loaded = LoadFile(filepath.c_str(), true, &contents); - if (included_files_.find(HashFile(filepath.c_str(), contents.c_str())) == - included_files_.end()) { - // We found an include file that we have not parsed yet. - // Parse it. - if (!file_loaded) return Error("unable to load include file: " + name); - ECHECK(DoParse(contents.c_str(), include_paths, filepath.c_str(), - name.c_str())); - // We generally do not want to output code for any included files: - if (!opts.generate_all) MarkGenerated(); - // Reset these just in case the included file had them, and the - // parent doesn't. - root_struct_def_ = nullptr; - file_identifier_.clear(); - file_extension_.clear(); - // This is the easiest way to continue this file after an include: - // instead of saving and restoring all the state, we simply start the - // file anew. This will cause it to encounter the same include - // statement again, but this time it will skip it, because it was - // entered into included_files_. - // This is recursive, but only go as deep as the number of include - // statements. - included_files_.erase(source_hash); - return DoParse(source, include_paths, source_filename, - include_filename); - } - EXPECT(';'); - } else { - break; - } - } - // Now parse all other kinds of declarations: - while (token_ != kTokenEof) { - if (opts.proto_mode) { - ECHECK(ParseProtoDecl()); - } else if (IsIdent("namespace")) { - ECHECK(ParseNamespace()); - } else if (token_ == '{') { - return NoError(); - } else if (IsIdent("enum")) { - ECHECK(ParseEnum(false, nullptr)); - } else if (IsIdent("union")) { - ECHECK(ParseEnum(true, nullptr)); - } else if (IsIdent("root_type")) { - NEXT(); - auto root_type = attribute_; - EXPECT(kTokenIdentifier); - ECHECK(ParseNamespacing(&root_type, nullptr)); - if (opts.root_type.empty()) { - if (!SetRootType(root_type.c_str())) - return Error("unknown root type: " + root_type); - if (root_struct_def_->fixed) return Error("root type must be a table"); - } - EXPECT(';'); - } else if (IsIdent("file_identifier")) { - NEXT(); - file_identifier_ = attribute_; - EXPECT(kTokenStringConstant); - if (file_identifier_.length() != FlatBufferBuilder::kFileIdentifierLength) - return Error("file_identifier must be exactly " + - NumToString(FlatBufferBuilder::kFileIdentifierLength) + - " characters"); - EXPECT(';'); - } else if (IsIdent("file_extension")) { - NEXT(); - file_extension_ = attribute_; - EXPECT(kTokenStringConstant); - EXPECT(';'); - } else if (IsIdent("include")) { - return Error("includes must come before declarations"); - } else if (IsIdent("attribute")) { - NEXT(); - auto name = attribute_; - if (Is(kTokenIdentifier)) { - NEXT(); - } else { - EXPECT(kTokenStringConstant); - } - EXPECT(';'); - known_attributes_[name] = false; - } else if (IsIdent("rpc_service")) { - ECHECK(ParseService()); - } else { - ECHECK(ParseDecl()); - } - } - return NoError(); -} - -CheckedError Parser::DoParseJson() { - if (token_ != '{') { - EXPECT('{'); - } else { - if (!root_struct_def_) return Error("no root type set to parse json with"); - if (builder_.GetSize()) { - return Error("cannot have more than one json object in a file"); - } - uoffset_t toff; - ECHECK(ParseTable(*root_struct_def_, nullptr, &toff)); - if (opts.size_prefixed) { - builder_.FinishSizePrefixed( - Offset<Table>(toff), - file_identifier_.length() ? file_identifier_.c_str() : nullptr); - } else { - builder_.Finish(Offset<Table>(toff), file_identifier_.length() - ? file_identifier_.c_str() - : nullptr); - } - } - // Check that JSON file doesn't contain more objects or IDL directives. - // Comments after JSON are allowed. - EXPECT(kTokenEof); - return NoError(); -} - -std::set<std::string> Parser::GetIncludedFilesRecursive( - const std::string &file_name) const { - std::set<std::string> included_files; - std::list<std::string> to_process; - - if (file_name.empty()) return included_files; - to_process.push_back(file_name); - - while (!to_process.empty()) { - std::string current = to_process.front(); - to_process.pop_front(); - included_files.insert(current); - - // Workaround the lack of const accessor in C++98 maps. - auto &new_files = - (*const_cast<std::map<std::string, std::set<std::string>> *>( - &files_included_per_file_))[current]; - for (auto it = new_files.begin(); it != new_files.end(); ++it) { - if (included_files.find(*it) == included_files.end()) - to_process.push_back(*it); - } - } - - return included_files; -} - -// Schema serialization functionality: - -template<typename T> bool compareName(const T *a, const T *b) { - return a->defined_namespace->GetFullyQualifiedName(a->name) < - b->defined_namespace->GetFullyQualifiedName(b->name); -} - -template<typename T> void AssignIndices(const std::vector<T *> &defvec) { - // Pre-sort these vectors, such that we can set the correct indices for them. - auto vec = defvec; - std::sort(vec.begin(), vec.end(), compareName<T>); - for (int i = 0; i < static_cast<int>(vec.size()); i++) vec[i]->index = i; -} - -void Parser::Serialize() { - builder_.Clear(); - AssignIndices(structs_.vec); - AssignIndices(enums_.vec); - std::vector<Offset<reflection::Object>> object_offsets; - for (auto it = structs_.vec.begin(); it != structs_.vec.end(); ++it) { - auto offset = (*it)->Serialize(&builder_, *this); - object_offsets.push_back(offset); - (*it)->serialized_location = offset.o; - } - std::vector<Offset<reflection::Enum>> enum_offsets; - for (auto it = enums_.vec.begin(); it != enums_.vec.end(); ++it) { - auto offset = (*it)->Serialize(&builder_, *this); - enum_offsets.push_back(offset); - (*it)->serialized_location = offset.o; - } - std::vector<Offset<reflection::Service>> service_offsets; - for (auto it = services_.vec.begin(); it != services_.vec.end(); ++it) { - auto offset = (*it)->Serialize(&builder_, *this); - service_offsets.push_back(offset); - (*it)->serialized_location = offset.o; - } - auto objs__ = builder_.CreateVectorOfSortedTables(&object_offsets); - auto enum__ = builder_.CreateVectorOfSortedTables(&enum_offsets); - auto fiid__ = builder_.CreateString(file_identifier_); - auto fext__ = builder_.CreateString(file_extension_); - auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets); - auto schema_offset = reflection::CreateSchema( - builder_, objs__, enum__, fiid__, fext__, - (root_struct_def_ ? root_struct_def_->serialized_location : 0), serv__, - static_cast<reflection::AdvancedFeatures>(advanced_features_)); - if (opts.size_prefixed) { - builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier()); - } else { - builder_.Finish(schema_offset, reflection::SchemaIdentifier()); - } -} - -static Namespace *GetNamespace( - const std::string &qualified_name, std::vector<Namespace *> &namespaces, - std::map<std::string, Namespace *> &namespaces_index) { - size_t dot = qualified_name.find_last_of('.'); - std::string namespace_name = (dot != std::string::npos) - ? std::string(qualified_name.c_str(), dot) - : ""; - Namespace *&ns = namespaces_index[namespace_name]; - - if (!ns) { - ns = new Namespace(); - namespaces.push_back(ns); - - size_t pos = 0; - - for (;;) { - dot = qualified_name.find('.', pos); - if (dot == std::string::npos) { break; } - ns->components.push_back(qualified_name.substr(pos, dot - pos)); - pos = dot + 1; - } - } - - return ns; -} - -Offset<reflection::Object> StructDef::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - std::vector<Offset<reflection::Field>> field_offsets; - for (auto it = fields.vec.begin(); it != fields.vec.end(); ++it) { - field_offsets.push_back((*it)->Serialize( - builder, static_cast<uint16_t>(it - fields.vec.begin()), parser)); - } - auto qualified_name = defined_namespace->GetFullyQualifiedName(name); - auto name__ = builder->CreateString(qualified_name); - auto flds__ = builder->CreateVectorOfSortedTables(&field_offsets); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateObject(*builder, name__, flds__, fixed, - static_cast<int>(minalign), - static_cast<int>(bytesize), attr__, docs__); -} - -bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) { - if (!DeserializeAttributes(parser, object->attributes())) return false; - DeserializeDoc(doc_comment, object->documentation()); - name = parser.UnqualifiedName(object->name()->str()); - predecl = false; - sortbysize = attributes.Lookup("original_order") == nullptr && !fixed; - const auto &of = *(object->fields()); - auto indexes = std::vector<uoffset_t>(of.size()); - for (uoffset_t i = 0; i < of.size(); i++) indexes[of.Get(i)->id()] = i; - size_t tmp_struct_size = 0; - for (size_t i = 0; i < indexes.size(); i++) { - auto field = of.Get(indexes[i]); - auto field_def = new FieldDef(); - if (!field_def->Deserialize(parser, field) || - fields.Add(field_def->name, field_def)) { - delete field_def; - return false; - } - if (fixed) { - // Recompute padding since that's currently not serialized. - auto size = InlineSize(field_def->value.type); - auto next_field = - i + 1 < indexes.size() ? of.Get(indexes[i + 1]) : nullptr; - tmp_struct_size += size; - field_def->padding = - next_field ? (next_field->offset() - field_def->value.offset) - size - : PaddingBytes(tmp_struct_size, minalign); - tmp_struct_size += field_def->padding; - } - } - FLATBUFFERS_ASSERT(static_cast<int>(tmp_struct_size) == object->bytesize()); - return true; -} - -Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder, - uint16_t id, - const Parser &parser) const { - auto name__ = builder->CreateString(name); - auto type__ = value.type.Serialize(builder); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - double d; - StringToNumber(value.constant.c_str(), &d); - return reflection::CreateField( - *builder, name__, type__, id, value.offset, - // Is uint64>max(int64) tested? - IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0, - // result may be platform-dependent if underlying is float (not double) - IsFloat(value.type.base_type) ? d : 0.0, deprecated, IsRequired(), key, - attr__, docs__, IsOptional()); - // TODO: value.constant is almost always "0", we could save quite a bit of - // space by sharing it. Same for common values of value.type. -} - -bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) { - name = field->name()->str(); - defined_namespace = parser.current_namespace_; - if (!value.type.Deserialize(parser, field->type())) return false; - value.offset = field->offset(); - if (IsInteger(value.type.base_type)) { - value.constant = NumToString(field->default_integer()); - } else if (IsFloat(value.type.base_type)) { - value.constant = FloatToString(field->default_real(), 16); - } - presence = FieldDef::MakeFieldPresence(field->optional(), field->required()); - key = field->key(); - if (!DeserializeAttributes(parser, field->attributes())) return false; - // TODO: this should probably be handled by a separate attribute - if (attributes.Lookup("flexbuffer")) { - flexbuffer = true; - parser.uses_flexbuffers_ = true; - if (value.type.base_type != BASE_TYPE_VECTOR || - value.type.element != BASE_TYPE_UCHAR) - return false; - } - if (auto nested = attributes.Lookup("nested_flatbuffer")) { - auto nested_qualified_name = - parser.current_namespace_->GetFullyQualifiedName(nested->constant); - nested_flatbuffer = parser.LookupStruct(nested_qualified_name); - if (!nested_flatbuffer) return false; - } - shared = attributes.Lookup("shared") != nullptr; - DeserializeDoc(doc_comment, field->documentation()); - return true; -} - -Offset<reflection::RPCCall> RPCCall::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - auto name__ = builder->CreateString(name); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateRPCCall( - *builder, name__, request->serialized_location, - response->serialized_location, attr__, docs__); -} - -bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) { - name = call->name()->str(); - if (!DeserializeAttributes(parser, call->attributes())) return false; - DeserializeDoc(doc_comment, call->documentation()); - request = parser.structs_.Lookup(call->request()->name()->str()); - response = parser.structs_.Lookup(call->response()->name()->str()); - if (!request || !response) { return false; } - return true; -} - -Offset<reflection::Service> ServiceDef::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - std::vector<Offset<reflection::RPCCall>> servicecall_offsets; - for (auto it = calls.vec.begin(); it != calls.vec.end(); ++it) { - servicecall_offsets.push_back((*it)->Serialize(builder, parser)); - } - auto qualified_name = defined_namespace->GetFullyQualifiedName(name); - auto name__ = builder->CreateString(qualified_name); - auto call__ = builder->CreateVector(servicecall_offsets); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateService(*builder, name__, call__, attr__, docs__); -} - -bool ServiceDef::Deserialize(Parser &parser, - const reflection::Service *service) { - name = parser.UnqualifiedName(service->name()->str()); - if (service->calls()) { - for (uoffset_t i = 0; i < service->calls()->size(); ++i) { - auto call = new RPCCall(); - if (!call->Deserialize(parser, service->calls()->Get(i)) || - calls.Add(call->name, call)) { - delete call; - return false; - } - } - } - if (!DeserializeAttributes(parser, service->attributes())) return false; - DeserializeDoc(doc_comment, service->documentation()); - return true; -} - -Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - std::vector<Offset<reflection::EnumVal>> enumval_offsets; - for (auto it = vals.vec.begin(); it != vals.vec.end(); ++it) { - enumval_offsets.push_back((*it)->Serialize(builder, parser)); - } - auto qualified_name = defined_namespace->GetFullyQualifiedName(name); - auto name__ = builder->CreateString(qualified_name); - auto vals__ = builder->CreateVector(enumval_offsets); - auto type__ = underlying_type.Serialize(builder); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateEnum(*builder, name__, vals__, is_union, type__, - attr__, docs__); -} - -bool EnumDef::Deserialize(Parser &parser, const reflection::Enum *_enum) { - name = parser.UnqualifiedName(_enum->name()->str()); - for (uoffset_t i = 0; i < _enum->values()->size(); ++i) { - auto val = new EnumVal(); - if (!val->Deserialize(parser, _enum->values()->Get(i)) || - vals.Add(val->name, val)) { - delete val; - return false; - } - } - is_union = _enum->is_union(); - if (!underlying_type.Deserialize(parser, _enum->underlying_type())) { - return false; - } - if (!DeserializeAttributes(parser, _enum->attributes())) return false; - DeserializeDoc(doc_comment, _enum->documentation()); - return true; -} - -Offset<reflection::EnumVal> EnumVal::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - auto name__ = builder->CreateString(name); - auto type__ = union_type.Serialize(builder); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateEnumVal( - *builder, name__, value, - union_type.struct_def ? union_type.struct_def->serialized_location : 0, - type__, docs__); -} - -bool EnumVal::Deserialize(const Parser &parser, - const reflection::EnumVal *val) { - name = val->name()->str(); - value = val->value(); - if (!union_type.Deserialize(parser, val->union_type())) return false; - DeserializeDoc(doc_comment, val->documentation()); - return true; -} - -Offset<reflection::Type> Type::Serialize(FlatBufferBuilder *builder) const { - return reflection::CreateType( - *builder, static_cast<reflection::BaseType>(base_type), - static_cast<reflection::BaseType>(element), - struct_def ? struct_def->index : (enum_def ? enum_def->index : -1), - fixed_length); -} - -bool Type::Deserialize(const Parser &parser, const reflection::Type *type) { - if (type == nullptr) return true; - base_type = static_cast<BaseType>(type->base_type()); - element = static_cast<BaseType>(type->element()); - fixed_length = type->fixed_length(); - if (type->index() >= 0) { - bool is_series = type->base_type() == reflection::Vector || - type->base_type() == reflection::Array; - if (type->base_type() == reflection::Obj || - (is_series && type->element() == reflection::Obj)) { - if (static_cast<size_t>(type->index()) < parser.structs_.vec.size()) { - struct_def = parser.structs_.vec[type->index()]; - struct_def->refcount++; - } else { - return false; - } - } else { - if (static_cast<size_t>(type->index()) < parser.enums_.vec.size()) { - enum_def = parser.enums_.vec[type->index()]; - } else { - return false; - } - } - } - return true; -} - -flatbuffers::Offset< - flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> -Definition::SerializeAttributes(FlatBufferBuilder *builder, - const Parser &parser) const { - std::vector<flatbuffers::Offset<reflection::KeyValue>> attrs; - for (auto kv = attributes.dict.begin(); kv != attributes.dict.end(); ++kv) { - auto it = parser.known_attributes_.find(kv->first); - FLATBUFFERS_ASSERT(it != parser.known_attributes_.end()); - if (parser.opts.binary_schema_builtins || !it->second) { - auto key = builder->CreateString(kv->first); - auto val = builder->CreateString(kv->second->constant); - attrs.push_back(reflection::CreateKeyValue(*builder, key, val)); - } - } - if (attrs.size()) { - return builder->CreateVectorOfSortedTables(&attrs); - } else { - return 0; - } -} - -bool Definition::DeserializeAttributes( - Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs) { - if (attrs == nullptr) return true; - for (uoffset_t i = 0; i < attrs->size(); ++i) { - auto kv = attrs->Get(i); - auto value = new Value(); - if (kv->value()) { value->constant = kv->value()->str(); } - if (attributes.Add(kv->key()->str(), value)) { - delete value; - return false; - } - parser.known_attributes_[kv->key()->str()]; - } - return true; -} - -/************************************************************************/ -/* DESERIALIZATION */ -/************************************************************************/ -bool Parser::Deserialize(const uint8_t *buf, const size_t size) { - flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t *>(buf), size); - bool size_prefixed = false; - if (!reflection::SchemaBufferHasIdentifier(buf)) { - if (!flatbuffers::BufferHasIdentifier(buf, reflection::SchemaIdentifier(), - true)) - return false; - else - size_prefixed = true; - } - auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer - : &reflection::VerifySchemaBuffer; - if (!verify_fn(verifier)) { return false; } - auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf) - : reflection::GetSchema(buf); - return Deserialize(schema); -} - -bool Parser::Deserialize(const reflection::Schema *schema) { - file_identifier_ = schema->file_ident() ? schema->file_ident()->str() : ""; - file_extension_ = schema->file_ext() ? schema->file_ext()->str() : ""; - std::map<std::string, Namespace *> namespaces_index; - - // Create defs without deserializing so references from fields to structs and - // enums can be resolved. - for (auto it = schema->objects()->begin(); it != schema->objects()->end(); - ++it) { - auto struct_def = new StructDef(); - struct_def->bytesize = it->bytesize(); - struct_def->fixed = it->is_struct(); - struct_def->minalign = it->minalign(); - if (structs_.Add(it->name()->str(), struct_def)) { - delete struct_def; - return false; - } - auto type = new Type(BASE_TYPE_STRUCT, struct_def, nullptr); - if (types_.Add(it->name()->str(), type)) { - delete type; - return false; - } - } - for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) { - auto enum_def = new EnumDef(); - if (enums_.Add(it->name()->str(), enum_def)) { - delete enum_def; - return false; - } - auto type = new Type(BASE_TYPE_UNION, nullptr, enum_def); - if (types_.Add(it->name()->str(), type)) { - delete type; - return false; - } - } - - // Now fields can refer to structs and enums by index. - for (auto it = schema->objects()->begin(); it != schema->objects()->end(); - ++it) { - std::string qualified_name = it->name()->str(); - auto struct_def = structs_.Lookup(qualified_name); - struct_def->defined_namespace = - GetNamespace(qualified_name, namespaces_, namespaces_index); - if (!struct_def->Deserialize(*this, *it)) { return false; } - if (schema->root_table() == *it) { root_struct_def_ = struct_def; } - } - for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) { - std::string qualified_name = it->name()->str(); - auto enum_def = enums_.Lookup(qualified_name); - enum_def->defined_namespace = - GetNamespace(qualified_name, namespaces_, namespaces_index); - if (!enum_def->Deserialize(*this, *it)) { return false; } - } - - if (schema->services()) { - for (auto it = schema->services()->begin(); it != schema->services()->end(); - ++it) { - std::string qualified_name = it->name()->str(); - auto service_def = new ServiceDef(); - service_def->defined_namespace = - GetNamespace(qualified_name, namespaces_, namespaces_index); - if (!service_def->Deserialize(*this, *it) || - services_.Add(qualified_name, service_def)) { - delete service_def; - return false; - } - } - } - advanced_features_ = schema->advanced_features(); - return true; -} - -std::string Parser::ConformTo(const Parser &base) { - for (auto sit = structs_.vec.begin(); sit != structs_.vec.end(); ++sit) { - auto &struct_def = **sit; - auto qualified_name = - struct_def.defined_namespace->GetFullyQualifiedName(struct_def.name); - auto struct_def_base = base.LookupStruct(qualified_name); - if (!struct_def_base) continue; - for (auto fit = struct_def.fields.vec.begin(); - fit != struct_def.fields.vec.end(); ++fit) { - auto &field = **fit; - auto field_base = struct_def_base->fields.Lookup(field.name); - if (field_base) { - if (field.value.offset != field_base->value.offset) - return "offsets differ for field: " + field.name; - if (field.value.constant != field_base->value.constant) - return "defaults differ for field: " + field.name; - if (!EqualByName(field.value.type, field_base->value.type)) - return "types differ for field: " + field.name; - } else { - // Doesn't have to exist, deleting fields is fine. - // But we should check if there is a field that has the same offset - // but is incompatible (in the case of field renaming). - for (auto fbit = struct_def_base->fields.vec.begin(); - fbit != struct_def_base->fields.vec.end(); ++fbit) { - field_base = *fbit; - if (field.value.offset == field_base->value.offset) { - if (!EqualByName(field.value.type, field_base->value.type)) - return "field renamed to different type: " + field.name; - break; - } - } - } - } - } - for (auto eit = enums_.vec.begin(); eit != enums_.vec.end(); ++eit) { - auto &enum_def = **eit; - auto qualified_name = - enum_def.defined_namespace->GetFullyQualifiedName(enum_def.name); - auto enum_def_base = base.enums_.Lookup(qualified_name); - if (!enum_def_base) continue; - for (auto evit = enum_def.Vals().begin(); evit != enum_def.Vals().end(); - ++evit) { - auto &enum_val = **evit; - auto enum_val_base = enum_def_base->Lookup(enum_val.name); - if (enum_val_base) { - if (enum_val != *enum_val_base) - return "values differ for enum: " + enum_val.name; - } - } - } - return ""; -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/reflection.cpp b/contrib/libs/flatbuffers/src/reflection.cpp deleted file mode 100644 index 2dedcb4f18..0000000000 --- a/contrib/libs/flatbuffers/src/reflection.cpp +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Copyright 2015 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 - * - * 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 "flatbuffers/reflection.h" - -#include "flatbuffers/util.h" - -// Helper functionality for reflection. - -namespace flatbuffers { - -int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data) { -// clang-format off - #define FLATBUFFERS_GET(T) static_cast<int64_t>(ReadScalar<T>(data)) - switch (type) { - case reflection::UType: - case reflection::Bool: - case reflection::UByte: return FLATBUFFERS_GET(uint8_t); - case reflection::Byte: return FLATBUFFERS_GET(int8_t); - case reflection::Short: return FLATBUFFERS_GET(int16_t); - case reflection::UShort: return FLATBUFFERS_GET(uint16_t); - case reflection::Int: return FLATBUFFERS_GET(int32_t); - case reflection::UInt: return FLATBUFFERS_GET(uint32_t); - case reflection::Long: return FLATBUFFERS_GET(int64_t); - case reflection::ULong: return FLATBUFFERS_GET(uint64_t); - case reflection::Float: return FLATBUFFERS_GET(float); - case reflection::Double: return FLATBUFFERS_GET(double); - case reflection::String: { - auto s = reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + - data); - return s ? StringToInt(s->c_str()) : 0; - } - default: return 0; // Tables & vectors do not make sense. - } - #undef FLATBUFFERS_GET - // clang-format on -} - -double GetAnyValueF(reflection::BaseType type, const uint8_t *data) { - switch (type) { - case reflection::Float: return static_cast<double>(ReadScalar<float>(data)); - case reflection::Double: return ReadScalar<double>(data); - case reflection::String: { - auto s = - reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + data); - if (s) { - double d; - StringToNumber(s->c_str(), &d); - return d; - } else { - return 0.0; - } - } - default: return static_cast<double>(GetAnyValueI(type, data)); - } -} - -std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data, - const reflection::Schema *schema, int type_index) { - switch (type) { - case reflection::Float: - case reflection::Double: return NumToString(GetAnyValueF(type, data)); - case reflection::String: { - auto s = - reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + data); - return s ? s->c_str() : ""; - } - case reflection::Obj: - if (schema) { - // Convert the table to a string. This is mostly for debugging purposes, - // and does NOT promise to be JSON compliant. - // Also prefixes the type. - auto &objectdef = *schema->objects()->Get(type_index); - auto s = objectdef.name()->str(); - if (objectdef.is_struct()) { - s += "(struct)"; // TODO: implement this as well. - } else { - auto table_field = reinterpret_cast<const Table *>( - ReadScalar<uoffset_t>(data) + data); - s += " { "; - auto fielddefs = objectdef.fields(); - for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { - auto &fielddef = **it; - if (!table_field->CheckField(fielddef.offset())) continue; - auto val = GetAnyFieldS(*table_field, fielddef, schema); - if (fielddef.type()->base_type() == reflection::String) { - std::string esc; - flatbuffers::EscapeString(val.c_str(), val.length(), &esc, true, - false); - val = esc; - } - s += fielddef.name()->str(); - s += ": "; - s += val; - s += ", "; - } - s += "}"; - } - return s; - } else { - return "(table)"; - } - case reflection::Vector: - return "[(elements)]"; // TODO: implement this as well. - case reflection::Union: return "(union)"; // TODO: implement this as well. - default: return NumToString(GetAnyValueI(type, data)); - } -} - -void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val) { -// clang-format off - #define FLATBUFFERS_SET(T) WriteScalar(data, static_cast<T>(val)) - switch (type) { - case reflection::UType: - case reflection::Bool: - case reflection::UByte: FLATBUFFERS_SET(uint8_t ); break; - case reflection::Byte: FLATBUFFERS_SET(int8_t ); break; - case reflection::Short: FLATBUFFERS_SET(int16_t ); break; - case reflection::UShort: FLATBUFFERS_SET(uint16_t); break; - case reflection::Int: FLATBUFFERS_SET(int32_t ); break; - case reflection::UInt: FLATBUFFERS_SET(uint32_t); break; - case reflection::Long: FLATBUFFERS_SET(int64_t ); break; - case reflection::ULong: FLATBUFFERS_SET(uint64_t); break; - case reflection::Float: FLATBUFFERS_SET(float ); break; - case reflection::Double: FLATBUFFERS_SET(double ); break; - // TODO: support strings - default: break; - } - #undef FLATBUFFERS_SET - // clang-format on -} - -void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val) { - switch (type) { - case reflection::Float: WriteScalar(data, static_cast<float>(val)); break; - case reflection::Double: WriteScalar(data, val); break; - // TODO: support strings. - default: SetAnyValueI(type, data, static_cast<int64_t>(val)); break; - } -} - -void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val) { - switch (type) { - case reflection::Float: - case reflection::Double: { - double d; - StringToNumber(val, &d); - SetAnyValueF(type, data, d); - break; - } - // TODO: support strings. - default: SetAnyValueI(type, data, StringToInt(val)); break; - } -} - -// Resize a FlatBuffer in-place by iterating through all offsets in the buffer -// and adjusting them by "delta" if they straddle the start offset. -// Once that is done, bytes can now be inserted/deleted safely. -// "delta" may be negative (shrinking). -// Unless "delta" is a multiple of the largest alignment, you'll create a small -// amount of garbage space in the buffer (usually 0..7 bytes). -// If your FlatBuffer's root table is not the schema's root table, you should -// pass in your root_table type as well. -class ResizeContext { - public: - ResizeContext(const reflection::Schema &schema, uoffset_t start, int delta, - std::vector<uint8_t> *flatbuf, - const reflection::Object *root_table = nullptr) - : schema_(schema), - startptr_(vector_data(*flatbuf) + start), - delta_(delta), - buf_(*flatbuf), - dag_check_(flatbuf->size() / sizeof(uoffset_t), false) { - auto mask = static_cast<int>(sizeof(largest_scalar_t) - 1); - delta_ = (delta_ + mask) & ~mask; - if (!delta_) return; // We can't shrink by less than largest_scalar_t. - // Now change all the offsets by delta_. - auto root = GetAnyRoot(vector_data(buf_)); - Straddle<uoffset_t, 1>(vector_data(buf_), root, vector_data(buf_)); - ResizeTable(root_table ? *root_table : *schema.root_table(), root); - // We can now add or remove bytes at start. - if (delta_ > 0) - buf_.insert(buf_.begin() + start, delta_, 0); - else - buf_.erase(buf_.begin() + start + delta_, buf_.begin() + start); - } - - // Check if the range between first (lower address) and second straddles - // the insertion point. If it does, change the offset at offsetloc (of - // type T, with direction D). - template<typename T, int D> - void Straddle(const void *first, const void *second, void *offsetloc) { - if (first <= startptr_ && second >= startptr_) { - WriteScalar<T>(offsetloc, ReadScalar<T>(offsetloc) + delta_ * D); - DagCheck(offsetloc) = true; - } - } - - // This returns a boolean that records if the corresponding offset location - // has been modified already. If so, we can't even read the corresponding - // offset, since it is pointing to a location that is illegal until the - // resize actually happens. - // This must be checked for every offset, since we can't know which offsets - // will straddle and which won't. - uint8_t &DagCheck(const void *offsetloc) { - auto dag_idx = reinterpret_cast<const uoffset_t *>(offsetloc) - - reinterpret_cast<const uoffset_t *>(vector_data(buf_)); - return dag_check_[dag_idx]; - } - - void ResizeTable(const reflection::Object &objectdef, Table *table) { - if (DagCheck(table)) return; // Table already visited. - auto vtable = table->GetVTable(); - // Early out: since all fields inside the table must point forwards in - // memory, if the insertion point is before the table we can stop here. - auto tableloc = reinterpret_cast<uint8_t *>(table); - if (startptr_ <= tableloc) { - // Check if insertion point is between the table and a vtable that - // precedes it. This can't happen in current construction code, but check - // just in case we ever change the way flatbuffers are built. - Straddle<soffset_t, -1>(vtable, table, table); - } else { - // Check each field. - auto fielddefs = objectdef.fields(); - for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { - auto &fielddef = **it; - auto base_type = fielddef.type()->base_type(); - // Ignore scalars. - if (base_type <= reflection::Double) continue; - // Ignore fields that are not stored. - auto offset = table->GetOptionalFieldOffset(fielddef.offset()); - if (!offset) continue; - // Ignore structs. - auto subobjectdef = - base_type == reflection::Obj - ? schema_.objects()->Get(fielddef.type()->index()) - : nullptr; - if (subobjectdef && subobjectdef->is_struct()) continue; - // Get this fields' offset, and read it if safe. - auto offsetloc = tableloc + offset; - if (DagCheck(offsetloc)) continue; // This offset already visited. - auto ref = offsetloc + ReadScalar<uoffset_t>(offsetloc); - Straddle<uoffset_t, 1>(offsetloc, ref, offsetloc); - // Recurse. - switch (base_type) { - case reflection::Obj: { - ResizeTable(*subobjectdef, reinterpret_cast<Table *>(ref)); - break; - } - case reflection::Vector: { - auto elem_type = fielddef.type()->element(); - if (elem_type != reflection::Obj && elem_type != reflection::String) - break; - auto vec = reinterpret_cast<Vector<uoffset_t> *>(ref); - auto elemobjectdef = - elem_type == reflection::Obj - ? schema_.objects()->Get(fielddef.type()->index()) - : nullptr; - if (elemobjectdef && elemobjectdef->is_struct()) break; - for (uoffset_t i = 0; i < vec->size(); i++) { - auto loc = vec->Data() + i * sizeof(uoffset_t); - if (DagCheck(loc)) continue; // This offset already visited. - auto dest = loc + vec->Get(i); - Straddle<uoffset_t, 1>(loc, dest, loc); - if (elemobjectdef) - ResizeTable(*elemobjectdef, reinterpret_cast<Table *>(dest)); - } - break; - } - case reflection::Union: { - ResizeTable(GetUnionType(schema_, objectdef, fielddef, *table), - reinterpret_cast<Table *>(ref)); - break; - } - case reflection::String: break; - default: FLATBUFFERS_ASSERT(false); - } - } - // Check if the vtable offset points beyond the insertion point. - // Must do this last, since GetOptionalFieldOffset above still reads - // this value. - Straddle<soffset_t, -1>(table, vtable, table); - } - } - - private: - const reflection::Schema &schema_; - uint8_t *startptr_; - int delta_; - std::vector<uint8_t> &buf_; - std::vector<uint8_t> dag_check_; -}; - -void SetString(const reflection::Schema &schema, const std::string &val, - const String *str, std::vector<uint8_t> *flatbuf, - const reflection::Object *root_table) { - auto delta = static_cast<int>(val.size()) - static_cast<int>(str->size()); - auto str_start = static_cast<uoffset_t>( - reinterpret_cast<const uint8_t *>(str) - vector_data(*flatbuf)); - auto start = str_start + static_cast<uoffset_t>(sizeof(uoffset_t)); - if (delta) { - // Clear the old string, since we don't want parts of it remaining. - memset(vector_data(*flatbuf) + start, 0, str->size()); - // Different size, we must expand (or contract). - ResizeContext(schema, start, delta, flatbuf, root_table); - // Set the new length. - WriteScalar(vector_data(*flatbuf) + str_start, - static_cast<uoffset_t>(val.size())); - } - // Copy new data. Safe because we created the right amount of space. - memcpy(vector_data(*flatbuf) + start, val.c_str(), val.size() + 1); -} - -uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize, - const VectorOfAny *vec, uoffset_t num_elems, - uoffset_t elem_size, std::vector<uint8_t> *flatbuf, - const reflection::Object *root_table) { - auto delta_elem = static_cast<int>(newsize) - static_cast<int>(num_elems); - auto delta_bytes = delta_elem * static_cast<int>(elem_size); - auto vec_start = - reinterpret_cast<const uint8_t *>(vec) - vector_data(*flatbuf); - auto start = static_cast<uoffset_t>(vec_start + sizeof(uoffset_t) + - elem_size * num_elems); - if (delta_bytes) { - if (delta_elem < 0) { - // Clear elements we're throwing away, since some might remain in the - // buffer. - auto size_clear = -delta_elem * elem_size; - memset(vector_data(*flatbuf) + start - size_clear, 0, size_clear); - } - ResizeContext(schema, start, delta_bytes, flatbuf, root_table); - WriteScalar(vector_data(*flatbuf) + vec_start, newsize); // Length field. - // Set new elements to 0.. this can be overwritten by the caller. - if (delta_elem > 0) { - memset(vector_data(*flatbuf) + start, 0, delta_elem * elem_size); - } - } - return vector_data(*flatbuf) + start; -} - -const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf, - const uint8_t *newbuf, size_t newlen) { - // Align to sizeof(uoffset_t) past sizeof(largest_scalar_t) since we're - // going to chop off the root offset. - while ((flatbuf.size() & (sizeof(uoffset_t) - 1)) || - !(flatbuf.size() & (sizeof(largest_scalar_t) - 1))) { - flatbuf.push_back(0); - } - auto insertion_point = static_cast<uoffset_t>(flatbuf.size()); - // Insert the entire FlatBuffer minus the root pointer. - flatbuf.insert(flatbuf.end(), newbuf + sizeof(uoffset_t), newbuf + newlen); - auto root_offset = ReadScalar<uoffset_t>(newbuf) - sizeof(uoffset_t); - return vector_data(flatbuf) + insertion_point + root_offset; -} - -void CopyInline(FlatBufferBuilder &fbb, const reflection::Field &fielddef, - const Table &table, size_t align, size_t size) { - fbb.Align(align); - fbb.PushBytes(table.GetStruct<const uint8_t *>(fielddef.offset()), size); - fbb.TrackField(fielddef.offset(), fbb.GetSize()); -} - -Offset<const Table *> CopyTable(FlatBufferBuilder &fbb, - const reflection::Schema &schema, - const reflection::Object &objectdef, - const Table &table, bool use_string_pooling) { - // Before we can construct the table, we have to first generate any - // subobjects, and collect their offsets. - std::vector<uoffset_t> offsets; - auto fielddefs = objectdef.fields(); - for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { - auto &fielddef = **it; - // Skip if field is not present in the source. - if (!table.CheckField(fielddef.offset())) continue; - uoffset_t offset = 0; - switch (fielddef.type()->base_type()) { - case reflection::String: { - offset = use_string_pooling - ? fbb.CreateSharedString(GetFieldS(table, fielddef)).o - : fbb.CreateString(GetFieldS(table, fielddef)).o; - break; - } - case reflection::Obj: { - auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index()); - if (!subobjectdef.is_struct()) { - offset = CopyTable(fbb, schema, subobjectdef, - *GetFieldT(table, fielddef), use_string_pooling) - .o; - } - break; - } - case reflection::Union: { - auto &subobjectdef = GetUnionType(schema, objectdef, fielddef, table); - offset = CopyTable(fbb, schema, subobjectdef, - *GetFieldT(table, fielddef), use_string_pooling) - .o; - break; - } - case reflection::Vector: { - auto vec = - table.GetPointer<const Vector<Offset<Table>> *>(fielddef.offset()); - auto element_base_type = fielddef.type()->element(); - auto elemobjectdef = - element_base_type == reflection::Obj - ? schema.objects()->Get(fielddef.type()->index()) - : nullptr; - switch (element_base_type) { - case reflection::String: { - std::vector<Offset<const String *>> elements(vec->size()); - auto vec_s = reinterpret_cast<const Vector<Offset<String>> *>(vec); - for (uoffset_t i = 0; i < vec_s->size(); i++) { - elements[i] = use_string_pooling - ? fbb.CreateSharedString(vec_s->Get(i)).o - : fbb.CreateString(vec_s->Get(i)).o; - } - offset = fbb.CreateVector(elements).o; - break; - } - case reflection::Obj: { - if (!elemobjectdef->is_struct()) { - std::vector<Offset<const Table *>> elements(vec->size()); - for (uoffset_t i = 0; i < vec->size(); i++) { - elements[i] = CopyTable(fbb, schema, *elemobjectdef, - *vec->Get(i), use_string_pooling); - } - offset = fbb.CreateVector(elements).o; - break; - } - } - FLATBUFFERS_FALLTHROUGH(); // fall thru - default: { // Scalars and structs. - auto element_size = GetTypeSize(element_base_type); - if (elemobjectdef && elemobjectdef->is_struct()) - element_size = elemobjectdef->bytesize(); - fbb.StartVector(vec->size(), element_size); - fbb.PushBytes(vec->Data(), element_size * vec->size()); - offset = fbb.EndVector(vec->size()); - break; - } - } - break; - } - default: // Scalars. - break; - } - if (offset) { offsets.push_back(offset); } - } - // Now we can build the actual table from either offsets or scalar data. - auto start = objectdef.is_struct() ? fbb.StartStruct(objectdef.minalign()) - : fbb.StartTable(); - size_t offset_idx = 0; - for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { - auto &fielddef = **it; - if (!table.CheckField(fielddef.offset())) continue; - auto base_type = fielddef.type()->base_type(); - switch (base_type) { - case reflection::Obj: { - auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index()); - if (subobjectdef.is_struct()) { - CopyInline(fbb, fielddef, table, subobjectdef.minalign(), - subobjectdef.bytesize()); - break; - } - } - FLATBUFFERS_FALLTHROUGH(); // fall thru - case reflection::Union: - case reflection::String: - case reflection::Vector: - fbb.AddOffset(fielddef.offset(), Offset<void>(offsets[offset_idx++])); - break; - default: { // Scalars. - auto size = GetTypeSize(base_type); - CopyInline(fbb, fielddef, table, size, size); - break; - } - } - } - FLATBUFFERS_ASSERT(offset_idx == offsets.size()); - if (objectdef.is_struct()) { - fbb.ClearOffsets(); - return fbb.EndStruct(); - } else { - return fbb.EndTable(start); - } -} - -bool VerifyStruct(flatbuffers::Verifier &v, - const flatbuffers::Table &parent_table, - voffset_t field_offset, const reflection::Object &obj, - bool required) { - auto offset = parent_table.GetOptionalFieldOffset(field_offset); - if (required && !offset) { return false; } - - return !offset || v.Verify(reinterpret_cast<const uint8_t *>(&parent_table), - offset, obj.bytesize()); -} - -bool VerifyVectorOfStructs(flatbuffers::Verifier &v, - const flatbuffers::Table &parent_table, - voffset_t field_offset, - const reflection::Object &obj, bool required) { - auto p = parent_table.GetPointer<const uint8_t *>(field_offset); - if (required && !p) { return false; } - - return !p || v.VerifyVectorOrString(p, obj.bytesize()); -} - -// forward declare to resolve cyclic deps between VerifyObject and VerifyVector -bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema, - const reflection::Object &obj, - const flatbuffers::Table *table, bool required); - -bool VerifyUnion(flatbuffers::Verifier &v, const reflection::Schema &schema, - uint8_t utype, const uint8_t *elem, - const reflection::Field &union_field) { - if (!utype) return true; // Not present. - auto fb_enum = schema.enums()->Get(union_field.type()->index()); - if (utype >= fb_enum->values()->size()) return false; - auto elem_type = fb_enum->values()->Get(utype)->union_type(); - switch (elem_type->base_type()) { - case reflection::Obj: { - auto elem_obj = schema.objects()->Get(elem_type->index()); - if (elem_obj->is_struct()) { - return v.VerifyFromPointer(elem, elem_obj->bytesize()); - } else { - return VerifyObject(v, schema, *elem_obj, - reinterpret_cast<const flatbuffers::Table *>(elem), - true); - } - } - case reflection::String: - return v.VerifyString( - reinterpret_cast<const flatbuffers::String *>(elem)); - default: return false; - } -} - -bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema, - const flatbuffers::Table &table, - const reflection::Field &vec_field) { - FLATBUFFERS_ASSERT(vec_field.type()->base_type() == reflection::Vector); - if (!table.VerifyField<uoffset_t>(v, vec_field.offset())) return false; - - switch (vec_field.type()->element()) { - case reflection::UType: - return v.VerifyVector(flatbuffers::GetFieldV<uint8_t>(table, vec_field)); - case reflection::Bool: - case reflection::Byte: - case reflection::UByte: - return v.VerifyVector(flatbuffers::GetFieldV<int8_t>(table, vec_field)); - case reflection::Short: - case reflection::UShort: - return v.VerifyVector(flatbuffers::GetFieldV<int16_t>(table, vec_field)); - case reflection::Int: - case reflection::UInt: - return v.VerifyVector(flatbuffers::GetFieldV<int32_t>(table, vec_field)); - case reflection::Long: - case reflection::ULong: - return v.VerifyVector(flatbuffers::GetFieldV<int64_t>(table, vec_field)); - case reflection::Float: - return v.VerifyVector(flatbuffers::GetFieldV<float>(table, vec_field)); - case reflection::Double: - return v.VerifyVector(flatbuffers::GetFieldV<double>(table, vec_field)); - case reflection::String: { - auto vec_string = - flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::String>>( - table, vec_field); - if (v.VerifyVector(vec_string) && v.VerifyVectorOfStrings(vec_string)) { - return true; - } else { - return false; - } - } - case reflection::Obj: { - auto obj = schema.objects()->Get(vec_field.type()->index()); - if (obj->is_struct()) { - return VerifyVectorOfStructs(v, table, vec_field.offset(), *obj, - vec_field.required()); - } else { - auto vec = - flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::Table>>( - table, vec_field); - if (!v.VerifyVector(vec)) return false; - if (!vec) return true; - for (uoffset_t j = 0; j < vec->size(); j++) { - if (!VerifyObject(v, schema, *obj, vec->Get(j), true)) { - return false; - } - } - return true; - } - } - case reflection::Union: { - auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>( - table, vec_field); - if (!v.VerifyVector(vec)) return false; - if (!vec) return true; - auto type_vec = table.GetPointer<Vector<uint8_t> *>(vec_field.offset() - - sizeof(voffset_t)); - if (!v.VerifyVector(type_vec)) return false; - for (uoffset_t j = 0; j < vec->size(); j++) { - // get union type from the prev field - auto utype = type_vec->Get(j); - auto elem = vec->Get(j); - if (!VerifyUnion(v, schema, utype, elem, vec_field)) return false; - } - return true; - } - case reflection::Vector: - case reflection::None: - default: FLATBUFFERS_ASSERT(false); return false; - } -} - -bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema, - const reflection::Object &obj, - const flatbuffers::Table *table, bool required) { - if (!table) return !required; - if (!table->VerifyTableStart(v)) return false; - for (uoffset_t i = 0; i < obj.fields()->size(); i++) { - auto field_def = obj.fields()->Get(i); - switch (field_def->type()->base_type()) { - case reflection::None: FLATBUFFERS_ASSERT(false); break; - case reflection::UType: - if (!table->VerifyField<uint8_t>(v, field_def->offset())) return false; - break; - case reflection::Bool: - case reflection::Byte: - case reflection::UByte: - if (!table->VerifyField<int8_t>(v, field_def->offset())) return false; - break; - case reflection::Short: - case reflection::UShort: - if (!table->VerifyField<int16_t>(v, field_def->offset())) return false; - break; - case reflection::Int: - case reflection::UInt: - if (!table->VerifyField<int32_t>(v, field_def->offset())) return false; - break; - case reflection::Long: - case reflection::ULong: - if (!table->VerifyField<int64_t>(v, field_def->offset())) return false; - break; - case reflection::Float: - if (!table->VerifyField<float>(v, field_def->offset())) return false; - break; - case reflection::Double: - if (!table->VerifyField<double>(v, field_def->offset())) return false; - break; - case reflection::String: - if (!table->VerifyField<uoffset_t>(v, field_def->offset()) || - !v.VerifyString(flatbuffers::GetFieldS(*table, *field_def))) { - return false; - } - break; - case reflection::Vector: - if (!VerifyVector(v, schema, *table, *field_def)) return false; - break; - case reflection::Obj: { - auto child_obj = schema.objects()->Get(field_def->type()->index()); - if (child_obj->is_struct()) { - if (!VerifyStruct(v, *table, field_def->offset(), *child_obj, - field_def->required())) { - return false; - } - } else { - if (!VerifyObject(v, schema, *child_obj, - flatbuffers::GetFieldT(*table, *field_def), - field_def->required())) { - return false; - } - } - break; - } - case reflection::Union: { - // get union type from the prev field - voffset_t utype_offset = field_def->offset() - sizeof(voffset_t); - auto utype = table->GetField<uint8_t>(utype_offset, 0); - auto uval = reinterpret_cast<const uint8_t *>( - flatbuffers::GetFieldT(*table, *field_def)); - if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; } - break; - } - default: FLATBUFFERS_ASSERT(false); break; - } - } - - if (!v.EndTable()) return false; - - return true; -} - -bool Verify(const reflection::Schema &schema, const reflection::Object &root, - const uint8_t *buf, size_t length, uoffset_t max_depth /*= 64*/, - uoffset_t max_tables /*= 1000000*/) { - Verifier v(buf, length, max_depth, max_tables); - return VerifyObject(v, schema, root, flatbuffers::GetAnyRoot(buf), true); -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/src/util.cpp b/contrib/libs/flatbuffers/src/util.cpp deleted file mode 100644 index 3670a01939..0000000000 --- a/contrib/libs/flatbuffers/src/util.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2016 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 - * - * 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. - */ - -// clang-format off -// Dont't remove `format off`, it prevent reordering of win-includes. - -#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__) || \ - defined(__QNXNTO__) -# define _POSIX_C_SOURCE 200809L -# define _XOPEN_SOURCE 700L -#endif - -#ifdef _WIN32 -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# ifndef NOMINMAX -# define NOMINMAX -# endif -# ifdef _MSC_VER -# include <crtdbg.h> -# endif -# include <windows.h> // Must be included before <direct.h> -# include <direct.h> -# include <winbase.h> -# undef interface // This is also important because of reasons -#endif -// clang-format on - -#include "flatbuffers/base.h" -#include "flatbuffers/util.h" - -#include <sys/stat.h> -#include <clocale> -#include <cstdlib> -#include <fstream> - -namespace flatbuffers { - -bool FileExistsRaw(const char *name) { - std::ifstream ifs(name); - return ifs.good(); -} - -bool LoadFileRaw(const char *name, bool binary, std::string *buf) { - if (DirExists(name)) return false; - std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in); - if (!ifs.is_open()) return false; - if (binary) { - // The fastest way to read a file into a string. - ifs.seekg(0, std::ios::end); - auto size = ifs.tellg(); - (*buf).resize(static_cast<size_t>(size)); - ifs.seekg(0, std::ios::beg); - ifs.read(&(*buf)[0], (*buf).size()); - } else { - // This is slower, but works correctly on all platforms for text files. - std::ostringstream oss; - oss << ifs.rdbuf(); - *buf = oss.str(); - } - return !ifs.bad(); -} - -static LoadFileFunction g_load_file_function = LoadFileRaw; -static FileExistsFunction g_file_exists_function = FileExistsRaw; - -bool LoadFile(const char *name, bool binary, std::string *buf) { - FLATBUFFERS_ASSERT(g_load_file_function); - return g_load_file_function(name, binary, buf); -} - -bool FileExists(const char *name) { - FLATBUFFERS_ASSERT(g_file_exists_function); - return g_file_exists_function(name); -} - -bool DirExists(const char *name) { - // clang-format off - - #ifdef _WIN32 - #define flatbuffers_stat _stat - #define FLATBUFFERS_S_IFDIR _S_IFDIR - #else - #define flatbuffers_stat stat - #define FLATBUFFERS_S_IFDIR S_IFDIR - #endif - // clang-format on - struct flatbuffers_stat file_info; - if (flatbuffers_stat(name, &file_info) != 0) return false; - return (file_info.st_mode & FLATBUFFERS_S_IFDIR) != 0; -} - -LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function) { - LoadFileFunction previous_function = g_load_file_function; - g_load_file_function = load_file_function ? load_file_function : LoadFileRaw; - return previous_function; -} - -FileExistsFunction SetFileExistsFunction( - FileExistsFunction file_exists_function) { - FileExistsFunction previous_function = g_file_exists_function; - g_file_exists_function = - file_exists_function ? file_exists_function : FileExistsRaw; - return previous_function; -} - -bool SaveFile(const char *name, const char *buf, size_t len, bool binary) { - std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out); - if (!ofs.is_open()) return false; - ofs.write(buf, len); - return !ofs.bad(); -} - -// We internally store paths in posix format ('/'). Paths supplied -// by the user should go through PosixPath to ensure correct behavior -// on Windows when paths are string-compared. - -static const char kPathSeparatorWindows = '\\'; -static const char *PathSeparatorSet = "\\/"; // Intentionally no ':' - -std::string StripExtension(const std::string &filepath) { - size_t i = filepath.find_last_of('.'); - return i != std::string::npos ? filepath.substr(0, i) : filepath; -} - -std::string GetExtension(const std::string &filepath) { - size_t i = filepath.find_last_of('.'); - return i != std::string::npos ? filepath.substr(i + 1) : ""; -} - -std::string StripPath(const std::string &filepath) { - size_t i = filepath.find_last_of(PathSeparatorSet); - return i != std::string::npos ? filepath.substr(i + 1) : filepath; -} - -std::string StripFileName(const std::string &filepath) { - size_t i = filepath.find_last_of(PathSeparatorSet); - return i != std::string::npos ? filepath.substr(0, i) : ""; -} - -std::string ConCatPathFileName(const std::string &path, - const std::string &filename) { - std::string filepath = path; - if (filepath.length()) { - char &filepath_last_character = string_back(filepath); - if (filepath_last_character == kPathSeparatorWindows) { - filepath_last_character = kPathSeparator; - } else if (filepath_last_character != kPathSeparator) { - filepath += kPathSeparator; - } - } - filepath += filename; - // Ignore './' at the start of filepath. - if (filepath[0] == '.' && filepath[1] == kPathSeparator) { - filepath.erase(0, 2); - } - return filepath; -} - -std::string PosixPath(const char *path) { - std::string p = path; - std::replace(p.begin(), p.end(), '\\', '/'); - return p; -} - -void EnsureDirExists(const std::string &filepath) { - auto parent = StripFileName(filepath); - if (parent.length()) EnsureDirExists(parent); - // clang-format off - - #ifdef _WIN32 - (void)_mkdir(filepath.c_str()); - #else - mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP); - #endif - // clang-format on -} - -std::string AbsolutePath(const std::string &filepath) { - // clang-format off - - #ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION - return filepath; - #else - #ifdef _WIN32 - char abs_path[MAX_PATH]; - return GetFullPathNameA(filepath.c_str(), MAX_PATH, abs_path, nullptr) - #else - char *abs_path_temp = realpath(filepath.c_str(), nullptr); - bool success = abs_path_temp != nullptr; - std::string abs_path; - if(success) { - abs_path = abs_path_temp; - free(abs_path_temp); - } - return success - #endif - ? abs_path - : filepath; - #endif // FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION - // clang-format on -} - -// Locale-independent code. -#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && \ - (FLATBUFFERS_LOCALE_INDEPENDENT > 0) - -// clang-format off -// Allocate locale instance at startup of application. -ClassicLocale ClassicLocale::instance_; - -#ifdef _MSC_VER - ClassicLocale::ClassicLocale() - : locale_(_create_locale(LC_ALL, "C")) {} - ClassicLocale::~ClassicLocale() { _free_locale(locale_); } -#else - ClassicLocale::ClassicLocale() - : locale_(newlocale(LC_ALL, "C", nullptr)) {} - ClassicLocale::~ClassicLocale() { freelocale(locale_); } -#endif -// clang-format on - -#endif // !FLATBUFFERS_LOCALE_INDEPENDENT - -std::string RemoveStringQuotes(const std::string &s) { - auto ch = *s.c_str(); - return ((s.size() >= 2) && (ch == '\"' || ch == '\'') && - (ch == string_back(s))) - ? s.substr(1, s.length() - 2) - : s; -} - -bool SetGlobalTestLocale(const char *locale_name, std::string *_value) { - const auto the_locale = setlocale(LC_ALL, locale_name); - if (!the_locale) return false; - if (_value) *_value = std::string(the_locale); - return true; -} - -bool ReadEnvironmentVariable(const char *var_name, std::string *_value) { -#ifdef _MSC_VER - __pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS -#endif - auto env_str = std::getenv(var_name); - if (!env_str) return false; - if (_value) *_value = std::string(env_str); - return true; -} - -void SetupDefaultCRTReportMode() { - // clang-format off - - #ifdef _MSC_VER - // By default, send all reports to STDOUT to prevent CI hangs. - // Enable assert report box [Abort|Retry|Ignore] if a debugger is present. - const int dbg_mode = (_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG) | - (IsDebuggerPresent() ? _CRTDBG_MODE_WNDW : 0); - (void)dbg_mode; // release mode fix - // CrtDebug reports to _CRT_WARN channel. - _CrtSetReportMode(_CRT_WARN, dbg_mode); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); - // The assert from <assert.h> reports to _CRT_ERROR channel - _CrtSetReportMode(_CRT_ERROR, dbg_mode); - _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); - // Internal CRT assert channel? - _CrtSetReportMode(_CRT_ASSERT, dbg_mode); - _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); - #endif - - // clang-format on -} - -} // namespace flatbuffers diff --git a/contrib/libs/flatbuffers/ya.make b/contrib/libs/flatbuffers/ya.make deleted file mode 100644 index 0fa3e01129..0000000000 --- a/contrib/libs/flatbuffers/ya.make +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by devtools/yamaker from nixpkgs 22.05. - -LIBRARY() - -VERSION(2.0.0) - -ORIGINAL_SOURCE(https://github.com/google/flatbuffers/archive/v2.0.0.tar.gz) - -LICENSE( - Apache-2.0 AND - BSD-3-Clause -) - -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - -ADDINCL( - contrib/libs/flatbuffers/include -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFLATBUFFERS_LOCALE_INDEPENDENT=1 -) - -SRCS( - src/idl_gen_text.cpp - src/idl_parser.cpp - src/reflection.cpp - src/util.cpp -) - -END() - -RECURSE( - flatc - samples -) |