Compare commits

..

78 Commits

Author SHA1 Message Date
Casper
615616cb55 Change Rust generated file defaults (#7101)
* Change Rust generated file defaults

After #6731, flatc changed its default behavior
for generating rust code to fix some importing issues.
This was a breaking change which invlidated the patch release,
`flatc 2.0.5` (#7081). This PR reverses the default so we can
release a patch update. However, does break Rust users who work at
HEAD.

* Bump flatc patch version (2.0.6)

Co-authored-by: Casper Neo <cneo@google.com>
2022-02-15 11:48:42 -05:00
Wouter van Oortmerssen
3413c33004 Fixed FlexBuffers verifier fuzzer timing out
Change-Id: I3a408da08676e522069adf83730d6bcc2b5493b3
2022-02-14 12:01:52 -08:00
Wouter van Oortmerssen
69f5660a44 Fixed Parser not checking size of union types vector
Change-Id: Ibcfc49a9c9376372bd15da2ed3a7f7a298863ccc
2022-02-14 11:48:46 -08:00
Wouter van Oortmerssen
d5add9fca5 Fixed FlexBuffers ToString unquoted non-ident keys
Change-Id: I0a17ee292c9eebbb1e9b2530c07d37d63b4dda24
2022-02-14 11:28:31 -08:00
Aaron Riekenberg
15df50eb7f Remove @ExperimentalUnsignedTypes annotation from kotlin code generator. (#7092) 2022-02-13 20:29:36 -08:00
Matt Grippaldi
a94132a45f Swift FlatBufferBuilder.sizedByteArray to ByteBuffer.toArray() (#7093)
* Moved code from FlatBufferBuilder.sizedByteArray to ByteBuffer.toArray() in Swift

* ByteBuffer.toArray() to  ByteBuffer.underlyingBytes
2022-02-11 13:26:16 -08:00
Björn Harrtell
48befb6bef [TS] Refactor away circular ref (#7099) 2022-02-11 09:40:09 -08:00
qazwsxedcrfvtg14
b300691336 Add reflection support for python (#7026)
We already have the reflection.fbs file and the flatbuffers
python language support.

Adding this feature would give the python developers the
ability to parse the flatbuffers schema and write some tools.

Co-authored-by: Derek Bailey <derekbailey@google.com>
2022-02-10 11:10:47 -08:00
Derek Bailey
faadbc10ea Add CreateVector overload to accept array like (#7095) 2022-02-09 22:16:46 -08:00
Derek Bailey
ed6ae8d322 explicitly defined std::allocator (#7094) 2022-02-09 15:09:52 -08:00
Timo Sturm
e910bddbcc [JS] Add ".js" suffix to all import statements to generate a browser compatible mjs version. (#7086) 2022-02-08 12:21:20 -08:00
Derek Bailey
c85fb690f4 Add Parsing Completed function for Rust (#7084) 2022-02-08 07:40:55 -08:00
Marcin Witkowski
c1daa6ba0c rust: Bump thiserror version and remove git dependency (#7080) 2022-02-04 16:02:02 -05:00
Derek Bailey
4c71c7b023 replace framework include of flatbuffers (#7079) 2022-02-03 17:40:15 -08:00
godcong
f5664d33fb fix go_test implement error (#7012)
* fix(grpc): fix go_test implement error

* fix(grpc): fix go_test implement error
2022-02-03 08:43:28 -08:00
Derek Bailey
39c8a19ce2 fixed comparator for native_inline (#7076)
* fixed comparator for native_inline

* added native_inline data

* updated more tests for the new field

* more fixes
2022-02-02 23:44:43 -08:00
Derek Bailey
826193ff68 skip generating reflection.fbs in generate_scripts (#7077) 2022-02-02 22:42:26 -08:00
Derek Bailey
fd0d1ed929 update C++ generator to emit scoped enums in vector of unions (#7075) 2022-02-02 22:29:21 -08:00
Derek Bailey
424988f308 replaced removed xml tag 2022-02-02 15:15:50 -08:00
Derek Bailey
b2550dbaa9 removed BSD-3-Clause license and Zlib licenses (#7073) 2022-02-02 13:12:01 -08:00
nicked
a2b238960f Fixed default value of bool in struct for Swift (#7072) 2022-02-02 23:39:19 +03:00
Derek Bailey
619b784374 one last dart omit local (#7070) 2022-02-01 22:25:52 -08:00
Derek Bailey
68a7661546 more omit type annotations for dart local variables (#7069) 2022-02-01 21:48:36 -08:00
Derek Bailey
7dac9961f0 omit type annotations for dart local variables (#7067)
* omit type annotations for dart local variables

* fixed some errors
2022-02-01 21:24:04 -08:00
Derek Bailey
c65c389c6d add xmlns to .Net (#7066) 2022-02-01 20:57:13 -08:00
mustiikhalil
6446dcf3d6 Updates swift gen licence for grpc code (#7063) 2022-02-01 14:23:38 -08:00
Derek Bailey
e090d8da17 Fixed long cast to int in flexbufferbuilder.java (#7059) 2022-02-01 12:58:10 -08:00
Derek Bailey
bc901436db clang format on codebase (#7058) 2022-02-01 11:23:18 -08:00
Derek Bailey
240be9b5ae attempt to remove appveyor (#7056) 2022-01-31 21:52:15 -08:00
Derek Bailey
bc366a7f9e Provide a short help text and default in error case (#6992)
* Provide a short help text and default in error case

* clean up short options a bit
2022-01-31 21:24:48 -08:00
Derek Bailey
14b19d446f Use FindPython3 (#7055) 2022-01-31 20:47:12 -08:00
Derek Bailey
9e6f17b94d remove BIICODE 2022-01-31 19:01:55 -08:00
Derek Bailey
c3801ad375 Update readme.md
Remove travis badge
Added Github action badge
Add dbaileychess twitter
2022-01-31 17:00:24 -08:00
mustiikhalil
4f3b24db09 Fixes a bug where bools arent being nil when marked optional (#7051) 2022-01-31 18:12:57 +03:00
Max Burke
1d294a31b8 Implement Serialize on generated rust types (#7022)
* fix for rust build

* Rust: Implement Serialize on generated types

For debugging convenience it is really handy to be able to dump out
types as another format (ie: json). For example, if we are logging a
type to a structured logging system, or even printing it out in a
structured way to the console.

Right now we handle this by shelling out to `flatc` which is not ideal;
by implementing Serialize on the generated types we can use any of the
Serializer-implementing packages for our structured debug output.

* clang-format

* Make the flatbuffers Rust crate only have an optional dependency on the `serde` packages.

* fix warning

* fix rust test build

* Oh yeah this needs to be initialized

* fix toml syntax

* code review feedback

* rebuild test data
2022-01-30 19:29:18 -05:00
Derek Bailey
dd8fccfb1b Cmake 3.16 de-facto minimum version (#7049) 2022-01-30 12:56:16 -08:00
Derek Bailey
7089c9ecdd Convert flatbuffers_version_string to inline function (#7046)
* Skip conditional for python executable

* replaced flatbuffers_version_string with inline function

* use const char* instead of string
2022-01-29 19:42:56 -08:00
Jean-François Roy
43203984f7 [C++] Support C++ object copies and moves (#5988)
Augment the C++ generator to emit a C++ copy constructor and a by-value
copy assignment operator. This is enabled by default when the C++
standard is C++11 or later. These additional functions are only emitted
for objects that need it, typically tables containing other tables.

These new functions are declared in the object table type and are
defined as inline functions after table declarations.

When these new functions are declared, a user-defined
explicitly-defaulted default constructor and move constructor are also
emitted.

The copy assignment operator uses the copy-and-swap idiom to provide
strong exception safety, at the expense of keeping 2 full table copies
in memory temporarily.

fixes #5783
2022-01-29 14:24:24 -08:00
Max Burke
5993338ee3 [ts] Builder incorrectly serializing empty strings (#7047)
* [ts] Builder incorrectly serializing empty strings

The builder was returning an offset of zero for empty strings. This is
leading to flatbuffers which fail verification in other languages, such
as Rust.

* tests expect 0 offset for null or undefined strings
2022-01-29 14:23:57 -08:00
Justin T Conroy
19920db39f Include a SizePrefixed..HasIdentifier for c++. (#6871)
* Include a SizePrefixed..HasIdentifier for c++.

* Add updated generated code.
2022-01-28 20:52:32 -08:00
Derek Bailey
dbbaeac85c Use ${PYTHON_EXECUTABLE} instead of py in cmake (#7042)
* Emit include for bfbs-gen-embed

* Use python3 explicitly

* bump min python version to 3.6

* Sort find_package for python

* try casting Path to string

* cast WindowsPath to string to please CI

* stringify the wrong thing

* another stringify path
2022-01-28 15:00:57 -08:00
Derek Bailey
028f0fde62 'flattest': Add --test_path option (#7041) 2022-01-27 14:21:01 -08:00
MS
87343631b9 Added support for clang-cl on windows (CMake) (#7038)
* Moved the CMake check for Clang *after* the one for MSVC, as clang-cl
  matches both Clang and MSVC.
* Removed /MP definition - controlled by CMake
* Added CPP define for _CRT_SECURE_NO_WARNINGS so clang can see it
  (it seems it doesnt pick up the pragma in util.cpp)
2022-01-27 10:48:01 -08:00
LouisP
1fbfaf5c5e Fix/cmake build grpc (#7028)
* BuildFlatbuffers.cmake: add verbose on build

* BuildFlatbuffers.cmake: properly add *.fb.* files with --grpc argument

When "--grpc" argument is provided as an extra flag, resulting grpc files
should be added as part of the interface library.
This prevent adding .fb.cc files manually to the build.

V2: fix dependency on grpc files
2022-01-25 20:57:31 -08:00
BogDan Vatra
4421375bb6 Add FlatBuffers::FlatBuffers interface, needed for FetchContent_Declare (#7023) 2022-01-25 20:51:00 -08:00
Jon Simantov
162ad7a37e Fix comment with line orders - Rust should be last. (#7037)
Fix for #6867.
2022-01-25 16:43:08 -08:00
Jon Simantov
a0a6c3f8c6 Use actions/checkout@v2, which fixes security vulnerability. (#7036)
Fix for issue #6999.
2022-01-25 16:19:05 -08:00
Jon Simantov
a2d38fbb98 Add --warnings-as-errors to flatc compiler. (#7034)
* Add --warnings-as-errors to flatc compiler.

With this option set, flatc will return an error on parsing if
any warnings occurred.

* Add unit test for opts.warnings_as_errors.

* Change explicit option setting to default.
2022-01-25 14:01:16 -08:00
Derek Bailey
9ef1524d3f Emit include for bfbs-gen-embed (#7031) 2022-01-25 10:43:16 -08:00
Derek Bailey
0c9de0352a Upgraded GRPC version to 1.42.0 (#7033) 2022-01-25 09:59:29 -08:00
Ivan Dlugos
a783bc9267 chore: dart 2.0.5 release changes (#6983) 2022-01-20 13:30:03 -08:00
Marcin Witkowski
aff818cebf rust: Allow for usage in no_std environment (#6989) 2022-01-20 11:49:02 -05:00
Danila Kutenin
d7b75417fc Make flatbuffer builder deterministic (#6993) 2022-01-14 15:37:27 -08:00
Wouter van Oortmerssen
a42e898979 Added verifier alignment checking to table fields (#7018) 2022-01-14 14:39:15 -08:00
LouisP
96cc2f3ee3 BuildFlatBuffers.cmake: fix arguments not passed properly to flatc (#7013)
Fix regression introduced by commit e9d4532401
2022-01-14 14:38:04 -08:00
Richard A Hofer
3250a1f8dd Add initial C# vector of unions support to the documentation. (#6880)
* Add initial C# vector of unions support to the documentation.

* Add notes about missing documentation for vector of unions.
2022-01-13 22:15:35 -08:00
Alex E
ace4a37f22 [TS/JS] BigInt implementation (#6998)
* BigInt implementation

* Unit test reading long from existing bytebuffer

* Code review
2022-01-06 20:35:37 -06:00
Advait Jain
f28c2b2936 Avoid implicit conversion from float to double. (#7003)
https://github.com/tensorflow/tflite-micro makes use of flatbuffers with
a variety of DSP toolchains.

Without the change from this PR, we can get a double-promotion warning
with some of these DSP toolchains:
```
flatbuffers/include/flatbuffers/util.h:104:11: error: implicit conversion increases floating-point precision: 'std::numeric_limits<float>::_Ty' (aka 'float') to 'double' [-Werror,-Wdouble-promotion]
  T eps = std::numeric_limits<float>::epsilon();
    ~~~   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
2021-12-23 20:31:30 -06:00
Shlomi Regev
96f3cf690f Rearrange #include directives to pass to compilation with a particular DSP toolchain (#7000)
iomanip isn't available for our DSP. Luckily, we compile with FLATBUFFERS_PREFER_PRINTF, so moved the #include directive there.
ctype.h has to be included explicilty for tolower() and toupper().
2021-12-22 10:40:38 -06:00
Panagiotis Gourgaris
b3edfdbfb7 Reverting grpc generated file suffix (#6995)
* Reverting grpc generated file suffix

* - Setting the greeter sample as it was
- Reverting the include of the generated message in grpc.cc file
2021-12-18 18:23:28 -08:00
Wouter van Oortmerssen
b8aaccee82 Disable parsing of nested_flatbuffers as bytes by default
Parsing as bytes produces buffers that are unsafe to access unless passed thru a verifier,
whereas users could reasonably assume that any JSON parsed without errors is safe to access.
Users that still have legacy JSON files with such bytes in it will get a helpful error point them
to the option to turn on to have it work again.
2021-12-15 10:41:29 -08:00
Wouter van Oortmerssen
2dc8ae7742 Enable OSS-Fuzz on CI 2021-12-14 12:10:43 -08:00
Wouter van Oortmerssen
5b0d491127 Updated FlexBuffers fuzzer 2021-12-14 11:57:42 -08:00
Wouter van Oortmerssen
d8b7041d7e Added alignment checking to FlexBuffers verifier 2021-12-14 11:20:23 -08:00
Wouter van Oortmerssen
5a0c3366c3 FlexBuffers verifier additionally checks for nesting 2021-12-14 11:20:23 -08:00
Wouter van Oortmerssen
f8148b8dad Made FlexBuffers reuse tracker track types 2021-12-14 11:20:23 -08:00
Derek Bailey
a22b1b6267 Prevent shadow with _{{FIELD_NAME}} (#6991) 2021-12-13 21:27:36 -08:00
Wouter van Oortmerssen
4264daadd2 FlexBuffers fuzzer fixes
- String dedup wasn't handling internal nulls correctly.
- Verifier wasn't recursing for certain types.
- Vector self-reference could create inf recursion.
2021-12-13 15:47:06 -08:00
Derek Bailey
3cbc120a08 Refractor Flatc Options (#6987)
* Moved error/warnings to bottom of std error

* Refactor flatc options

* pass program name to flatc

* extra -- in one option

* merge of upstream
2021-12-13 13:56:47 -08:00
Vadim-Valdis Yudaev
8dcd2682c7 [CMake] Add option for disable universal on OSX (#6990)
See https://github.com/google/flatbuffers/issues/6988
2021-12-13 13:32:58 -08:00
Derek Bailey
b78002ff3e Validate C# json/object-api options (#6985) 2021-12-13 11:52:01 -08:00
Derek Bailey
c555ee8fac Add .NET test to github workflows (#6982) 2021-12-13 11:51:27 -08:00
Biswapriyo Nath
b92bb0584d [CMake]: Fix version in pkgconfig file (#6986)
This change checks if the current source directory is a git repository.
If this is not checked the git command picks the commit hash from
parent directory. e.g. when tarball is extracted in a packaging repository.
2021-12-10 15:40:21 -08:00
Wouter van Oortmerssen
956d11569e re-enabled FlexBuffer JSON in fuzzer 2021-12-10 15:22:06 -08:00
Wouter van Oortmerssen
e367ca32ad Verifier for FlexBuffers (#6977)
* Verifier for FlexBuffers

* Verifier improvements & fuzzer
2021-12-10 14:59:08 -08:00
Biswapriyo Nath
705f27f6ee [CMake]: Fix python command for mingw environment (#6984)
In mingw build environment, this fixes the build error:
'py' is not recognized as an internal or external command
The 'py' launcher is available for MSVC python only. More
https://docs.python.org/3/using/windows.html#from-the-command-line
2021-12-10 11:28:24 -08:00
lu-wang-g
5fc87f4c4b Enable --gen-onefile in Python (#6953)
* Enable --gen-onefile in Python

Made it possible to generate all python code in one file. Modified
py_test.py so that it can switch between the multi-file code and
the one-file code.

Updated PythonTest.sh and py_test.py so that the multi-file code
and the one-file code can be tested based on the same test code.

* Sync with google/flatbuffers

* Add --gen-onefile to generate_code.py
2021-12-09 15:47:09 -08:00
Danila Kutenin
11749095a1 Make idl_parser deterministic (#6976)
* Make idl_parser deterministic

Some golden tests even exercise this [logic](df2df21ec1/tests/prototest/test.golden (L8)). Let's make the parser fully stable not depending on the implementation of std::sort

* Retry the ci
2021-12-09 13:07:29 -08:00
271 changed files with 16747 additions and 4930 deletions

2
.github/labeler.yml vendored
View File

@@ -86,11 +86,9 @@ documentation:
CI:
- '.github/**/*'
- '.appveyor/**/*'
- '.travis/**/*'
- '.bazelci/**/*'
- .travis.yml
- appveyor.yml
grpc:
- grpc/**/*

View File

@@ -16,7 +16,7 @@ jobs:
matrix:
cxx: [g++-10, clang++-12]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: cmake
run: CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .
- name: build
@@ -37,7 +37,7 @@ jobs:
name: Build Windows 2019
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1
- name: cmake
@@ -56,7 +56,7 @@ jobs:
name: Build Windows 2017
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1
- name: cmake
@@ -70,7 +70,7 @@ jobs:
name: Build Windows 2015
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1
- name: cmake
@@ -80,11 +80,39 @@ jobs:
- name: test
run: Release\flattests.exe
build-dotnet-windows:
name: Build .NET Windows
runs-on: windows-latest
strategy:
matrix:
configuration: [
'',
'-p:UnsafeByteBuffer=true',
# Fails two tests currently.
#'-p:EnableSpanT=true,UnsafeByteBuffer=true'
]
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v1.9.0
with:
dotnet-version: '3.1.x'
- name: Build
run: |
cd tests\FlatBuffers.Test
dotnet new sln --force --name FlatBuffers.Core.Test
dotnet sln FlatBuffers.Core.Test.sln add FlatBuffers.Core.Test.csproj
dotnet build -c Release ${{matrix.configuration}} -o out FlatBuffers.Core.Test.sln
- name: Run
run: |
cd tests\FlatBuffers.Test
out\FlatBuffers.Core.Test.exe
build-mac:
name: Build Mac
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: cmake
run: cmake -G "Xcode" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_FLATC_EXECUTABLE=_build/Release/flatc .
- name: build
@@ -111,7 +139,7 @@ jobs:
name: Build Android (on Linux)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
@@ -132,7 +160,7 @@ jobs:
matrix:
cxx: [g++-10, clang++-12]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: cmake
run: CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" -DFLATBUFFERS_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release . && make -j4
- name: Generate
@@ -147,7 +175,7 @@ jobs:
matrix:
cxx: [g++-10]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: cmake
run: CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" -DFLATBUFFERS_CXX_FLAGS="-Wno-unused-parameter -fno-aligned-new" -DFLATBUFFERS_BUILD_BENCHMARKS=ON -DCMAKE_BUILD_TYPE=Release . && make -j4
- name: Run benchmarks
@@ -162,7 +190,7 @@ jobs:
name: Build Java
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: test
working-directory: tests
run: bash JavaTest.sh
@@ -212,7 +240,7 @@ jobs:
name: Build Rust
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: test
working-directory: tests
run: bash RustTest.sh
@@ -221,7 +249,7 @@ jobs:
name: Build Python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: test
working-directory: tests
run: bash PythonTest.sh
@@ -230,7 +258,7 @@ jobs:
name: Build Go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: flatc
# FIXME: make test script not rely on flatc
run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . && make -j4
@@ -242,7 +270,7 @@ jobs:
name: Build Swift
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: test
working-directory: tests/FlatBuffers.Test.Swift
run: sh SwiftTest.sh
@@ -251,7 +279,7 @@ jobs:
name: Build TS
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: compile
run: npm run compile
- name: test
@@ -262,7 +290,7 @@ jobs:
name: Build Dart
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- uses: dart-lang/setup-dart@v1
with:
sdk: stable

24
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: CIFuzz
on: [pull_request]
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'flatbuffers'
language: c++
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'flatbuffers'
language: c++
fuzz-seconds: 600
- name: Upload Crash
uses: actions/upload-artifact@v1
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts

View File

@@ -95,7 +95,7 @@ function(build_flatbuffers flatbuffers_schemas
set(generated_include ${generated_includes_dir}/${filename}_generated.h)
add_custom_command(
OUTPUT ${generated_include}
COMMAND ${FLATC} ${FLATC_ARGS}
COMMAND ${FLATC} ${FLATC_SCHEMA_ARGS}
-o ${generated_includes_dir}
${include_params}
-c ${schema}
@@ -230,16 +230,30 @@ function(flatbuffers_generate_headers)
foreach(schema ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
get_filename_component(filename ${schema} NAME_WE)
set(generated_include "${generated_include_dir}/${filename}_generated.h")
# Generate files for grpc if needed
set(generated_source_file)
if("${FLATBUFFERS_GENERATE_HEADERS_FLAGS}" MATCHES "--grpc")
# Check if schema file contain a rpc_service definition
file(STRINGS ${schema} has_grpc REGEX "rpc_service")
if(has_grpc)
list(APPEND generated_include "${generated_include_dir}/${filename}.grpc.fb.h")
set(generated_source_file "${generated_include_dir}/${filename}.grpc.fb.cc")
endif()
endif()
add_custom_command(
OUTPUT ${generated_include}
OUTPUT ${generated_include} ${generated_source_file}
COMMAND ${FLATC} ${FLATC_ARGS}
-o ${generated_include_dir}
${include_params}
-c ${schema}
${FLATBUFFERS_GENERATE_HEADERS_FLAGS}
DEPENDS ${FLATC_TARGET} ${schema}
WORKING_DIRECTORY "${working_dir}")
WORKING_DIRECTORY "${working_dir}"
COMMENT "Building ${schema} flatbuffers...")
list(APPEND all_generated_header_files ${generated_include})
list(APPEND all_generated_source_files ${generated_source_file})
# Geneate the binary flatbuffers schemas if instructed to.
if (NOT ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} STREQUAL "")
@@ -264,6 +278,7 @@ function(flatbuffers_generate_headers)
INTERFACE
${all_generated_header_files}
${all_generated_binary_files}
${all_generated_source_files}
${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
add_dependencies(
${FLATBUFFERS_GENERATE_HEADERS_TARGET}
@@ -278,6 +293,10 @@ function(flatbuffers_generate_headers)
TREE "${generated_target_dir}"
PREFIX "Flatbuffers/Generated/Headers Files"
FILES ${all_generated_header_files})
source_group(
TREE "${generated_target_dir}"
PREFIX "Flatbuffers/Generated/Source Files"
FILES ${all_generated_source_files})
source_group(
TREE ${working_dir}
PREFIX "Flatbuffers/Schemas"
@@ -371,7 +390,8 @@ function(flatbuffers_generate_binary_files)
-b ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA} ${json_file}
${FLATBUFFERS_GENERATE_BINARY_FILES_FLAGS}
DEPENDS ${FLATC_TARGET} ${json_file}
WORKING_DIRECTORY "${working_dir}")
WORKING_DIRECTORY "${working_dir}"
COMMENT "Building ${json_file} binary flatbuffers...")
list(APPEND all_generated_binary_files ${generated_binary_file})
endforeach()

View File

@@ -0,0 +1,774 @@
# This was the legacy <root>/CMakeLists.txt that supported cmake version 2.8.12.
# It was originally copied on Jan 30 2022, and is conditionally included in the
# current <root>/CMakeLists.txt if the cmake version used is older than the new
# minimum version.
#
# Only add to this file to fix immediate issues or if a change cannot be made
# <root>/CMakeList.txt in a compatible way.
if (POLICY CMP0048)
cmake_policy(SET CMP0048 NEW)
project(FlatBuffers
DESCRIPTION "Flatbuffers serialization library"
VERSION 2.0.0
LANGUAGES CXX)
else()
project(FlatBuffers)
endif (POLICY CMP0048)
include(CMake/Version.cmake)
# generate compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# NOTE: Code coverage only works on Linux & OSX.
option(FLATBUFFERS_CODE_COVERAGE "Enable the code coverage build option." OFF)
option(FLATBUFFERS_BUILD_TESTS "Enable the build of tests and samples." ON)
option(FLATBUFFERS_INSTALL "Enable the installation of targets." ON)
option(FLATBUFFERS_BUILD_FLATLIB "Enable the build of the flatbuffers library"
ON)
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
ON)
option(FLATBUFFERS_STATIC_FLATC "Build flatbuffers compiler with -static flag"
OFF)
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
option(FLATBUFFERS_BUILD_BENCHMARKS "Enable the build of flatbenchmark. \"
Requires C++11."
OFF)
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
option(FLATBUFFERS_BUILD_SHAREDLIB
"Enable the build of the flatbuffers shared library"
OFF)
option(FLATBUFFERS_LIBCXX_WITH_CLANG "Force libc++ when using Clang" ON)
# NOTE: Sanitizer check only works on Linux & OSX (gcc & llvm).
option(FLATBUFFERS_CODE_SANITIZE
"Add '-fsanitize' flags to 'flattests' and 'flatc' targets."
OFF)
option(FLATBUFFERS_PACKAGE_REDHAT
"Build an rpm using the 'package' target."
OFF)
option(FLATBUFFERS_PACKAGE_DEBIAN
"Build an deb using the 'package' target."
OFF)
option(FLATBUFFERS_BUILD_CPP17
"Enable the build of c++17 test target. \"
Requirements: Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher."
OFF)
option(FLATBUFFERS_BUILD_LEGACY
"Run C++ code generator with '--cpp-std c++0x' switch."
OFF)
option(FLATBUFFERS_ENABLE_PCH
"Enable precompile headers support for 'flatbuffers' and 'flatc'. \"
Only work if CMake supports 'target_precompile_headers'. \"
This can speed up compilation time."
OFF)
option(FLATBUFFERS_SKIP_MONSTER_EXTRA
"Skip generating monster_extra.fbs that contains non-supported numerical\"
types." OFF)
option(FLATBUFFERS_OSX_BUILD_UNIVERSAL
"Enable the build for multiple architectures on OS X (arm64, x86_64)."
ON)
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
message(WARNING
"Cannot build tests without building the compiler. Tests will be disabled.")
set(FLATBUFFERS_BUILD_TESTS OFF)
endif()
if(DEFINED FLATBUFFERS_MAX_PARSING_DEPTH)
# Override the default recursion depth limit.
add_definitions(-DFLATBUFFERS_MAX_PARSING_DEPTH=${FLATBUFFERS_MAX_PARSING_DEPTH})
message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")
endif()
# Auto-detect locale-narrow 'strtod_l' and 'strtoull_l' functions.
if(NOT DEFINED FLATBUFFERS_LOCALE_INDEPENDENT)
include(CheckCXXSymbolExists)
set(FLATBUFFERS_LOCALE_INDEPENDENT 0)
if(MSVC)
check_cxx_symbol_exists(_strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
check_cxx_symbol_exists(_strtoui64_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
else()
check_cxx_symbol_exists(strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
check_cxx_symbol_exists(strtoull_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
endif()
if(FLATBUFFERS_HAS_STRTOF_L AND FLATBUFFERS_HAS_STRTOULL_L)
set(FLATBUFFERS_LOCALE_INDEPENDENT 1)
endif()
endif()
add_definitions(-DFLATBUFFERS_LOCALE_INDEPENDENT=$<BOOL:${FLATBUFFERS_LOCALE_INDEPENDENT}>)
set(FlatBuffers_Library_SRCS
include/flatbuffers/allocator.h
include/flatbuffers/array.h
include/flatbuffers/base.h
include/flatbuffers/bfbs_generator.h
include/flatbuffers/buffer.h
include/flatbuffers/buffer_ref.h
include/flatbuffers/default_allocator.h
include/flatbuffers/detached_buffer.h
include/flatbuffers/flatbuffer_builder.h
include/flatbuffers/flatbuffers.h
include/flatbuffers/flexbuffers.h
include/flatbuffers/hash.h
include/flatbuffers/idl.h
include/flatbuffers/minireflect.h
include/flatbuffers/reflection.h
include/flatbuffers/reflection_generated.h
include/flatbuffers/registry.h
include/flatbuffers/stl_emulation.h
include/flatbuffers/string.h
include/flatbuffers/struct.h
include/flatbuffers/table.h
include/flatbuffers/util.h
include/flatbuffers/vector.h
include/flatbuffers/vector_downward.h
include/flatbuffers/verifier.h
src/idl_parser.cpp
src/idl_gen_text.cpp
src/reflection.cpp
src/util.cpp
)
set(FlatBuffers_Compiler_SRCS
${FlatBuffers_Library_SRCS}
src/idl_gen_cpp.cpp
src/idl_gen_csharp.cpp
src/idl_gen_dart.cpp
src/idl_gen_kotlin.cpp
src/idl_gen_go.cpp
src/idl_gen_java.cpp
src/idl_gen_ts.cpp
src/idl_gen_php.cpp
src/idl_gen_python.cpp
src/idl_gen_lobster.cpp
src/idl_gen_lua.cpp
src/idl_gen_rust.cpp
src/idl_gen_fbs.cpp
src/idl_gen_grpc.cpp
src/idl_gen_json_schema.cpp
src/idl_gen_swift.cpp
src/flatc.cpp
src/flatc_main.cpp
src/bfbs_gen.h
src/bfbs_gen_lua.h
include/flatbuffers/code_generators.h
src/bfbs_gen_lua.cpp
src/code_generators.cpp
grpc/src/compiler/schema_interface.h
grpc/src/compiler/cpp_generator.h
grpc/src/compiler/cpp_generator.cc
grpc/src/compiler/go_generator.h
grpc/src/compiler/go_generator.cc
grpc/src/compiler/java_generator.h
grpc/src/compiler/java_generator.cc
grpc/src/compiler/python_generator.h
grpc/src/compiler/python_generator.cc
grpc/src/compiler/swift_generator.h
grpc/src/compiler/swift_generator.cc
grpc/src/compiler/ts_generator.h
grpc/src/compiler/ts_generator.cc
)
set(FlatHash_SRCS
include/flatbuffers/hash.h
src/flathash.cpp
)
set(FlatBuffers_Tests_SRCS
${FlatBuffers_Library_SRCS}
src/idl_gen_fbs.cpp
tests/test.cpp
tests/test_assert.h
tests/test_assert.cpp
tests/test_builder.h
tests/test_builder.cpp
tests/native_type_test_impl.h
tests/native_type_test_impl.cpp
include/flatbuffers/code_generators.h
src/code_generators.cpp
# file generate by running compiler on tests/monster_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
# file generate by running compiler on namespace_test/namespace_test1.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test1_generated.h
${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test2_generated.h
# file generate by running compiler on union_vector/union_vector.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/union_vector/union_vector_generated.h
# file generate by running compiler on tests/arrays_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/arrays_test_generated.h
# file generate by running compiler on tests/native_type_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/native_type_test_generated.h
# file generate by running compiler on tests/monster_extra.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_extra_generated.h
# file generate by running compiler on tests/monster_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_bfbs_generated.h
# file generate by running compiler on tests/optional_scalars.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/optional_scalars_generated.h
)
set(FlatBuffers_Tests_CPP17_SRCS
${FlatBuffers_Library_SRCS}
tests/test_assert.h
tests/test_assert.cpp
tests/cpp17/test_cpp17.cpp
# file generate by running compiler on tests/monster_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/cpp17/generated_cpp17/monster_test_generated.h
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
${CMAKE_CURRENT_BINARY_DIR}/tests/cpp17/generated_cpp17/optional_scalars_generated.h
${CMAKE_CURRENT_BINARY_DIR}/tests/optional_scalars_generated.h
)
set(FlatBuffers_Sample_Binary_SRCS
include/flatbuffers/flatbuffers.h
samples/sample_binary.cpp
# file generated by running compiler on samples/monster.fbs
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
)
set(FlatBuffers_Sample_Text_SRCS
${FlatBuffers_Library_SRCS}
samples/sample_text.cpp
# file generated by running compiler on samples/monster.fbs
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
)
set(FlatBuffers_Sample_BFBS_SRCS
${FlatBuffers_Library_SRCS}
samples/sample_bfbs.cpp
# file generated by running compiler on samples/monster.fbs
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
)
set(FlatBuffers_GRPCTest_SRCS
include/flatbuffers/flatbuffers.h
include/flatbuffers/grpc.h
include/flatbuffers/util.h
src/util.cpp
tests/monster_test.grpc.fb.h
tests/test_assert.h
tests/test_builder.h
tests/monster_test.grpc.fb.cc
tests/test_assert.cpp
tests/test_builder.cpp
grpc/tests/grpctest.cpp
grpc/tests/message_builder_test.cpp
# file generate by running compiler on tests/monster_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
)
# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
# source_group(Tests FILES ${FlatBuffers_Tests_SRCS})
if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
# do not apply any global settings if the toolchain
# is being configured externally
message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.")
elseif(CMAKE_COMPILER_IS_GNUCXX)
if(CYGWIN)
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -std=gnu++11")
else(CYGWIN)
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -std=c++0x")
endif(CYGWIN)
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra -Werror=shadow")
set(FLATBUFFERS_PRIVATE_CXX_FLAGS "-Wold-style-cast")
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.4)
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -faligned-new -Werror=implicit-fallthrough=2")
endif()
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wunused-result -Werror=unused-result -Wunused-parameter -Werror=unused-parameter")
endif()
# Certain platforms such as ARM do not use signed chars by default
# which causes issues with certain bounds checks.
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -fsigned-char")
# MSVC **MUST** come before the Clang check, as clang-cl is flagged by CMake as "MSVC", but it still textually
# matches as Clang in its Compiler Id :)
# Note: in CMake >= 3.14 we can check CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" or "MSVC" to differentiate...
elseif(MSVC)
# Visual Studio pedantic build settings
# warning C4512: assignment operator could not be generated
# warning C4316: object allocated on the heap may not be aligned
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /wd4512 /wd4316")
if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_WARNINGS")
endif()
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if(FLATBUFFERS_OSX_BUILD_UNIVERSAL)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
endif()
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra -Wno-unused-parameter")
set(FLATBUFFERS_PRIVATE_CXX_FLAGS "-Wold-style-cast")
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.8)
list(APPEND FLATBUFFERS_PRIVATE_CXX_FLAGS "-Wimplicit-fallthrough" "-Wextra-semi" "-Werror=unused-private-field") # enable warning
endif()
if(FLATBUFFERS_LIBCXX_WITH_CLANG)
if(NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
if(NOT ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD" OR
"${CMAKE_SYSTEM_NAME}" MATCHES "Linux"))
set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -lc++abi")
endif()
endif()
# Certain platforms such as ARM do not use signed chars by default
# which causes issues with certain bounds checks.
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -fsigned-char")
endif()
# Append FLATBUFFERS_CXX_FLAGS to CMAKE_CXX_FLAGS.
if(DEFINED FLATBUFFERS_CXX_FLAGS AND NOT EXISTS "${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "extend CXX_FLAGS with ${FLATBUFFERS_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLATBUFFERS_CXX_FLAGS}")
endif()
message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
if(FLATBUFFERS_CODE_COVERAGE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
function(add_fsanitize_to_target _target _sanitizer)
if(WIN32)
target_compile_definitions(${_target} PRIVATE FLATBUFFERS_MEMORY_LEAK_TRACKING)
message(STATUS "Sanitizer MSVC::_CrtDumpMemoryLeaks added to ${_target}")
else()
# FLATBUFFERS_CODE_SANITIZE: boolean {ON,OFF,YES,NO} or string with list of sanitizer.
# List of sanitizer is string starts with '=': "=address,undefined,thread,memory".
if((${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") OR
((${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9"))
)
set(_sanitizer_flags "=address,undefined")
if(_sanitizer MATCHES "=.*")
# override default by user-defined sanitizer list
set(_sanitizer_flags ${_sanitizer})
endif()
target_compile_options(${_target} PRIVATE
-g -fsigned-char -fno-omit-frame-pointer
"-fsanitize${_sanitizer_flags}")
target_link_libraries(${_target} PRIVATE
"-fsanitize${_sanitizer_flags}")
set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ON)
message(STATUS "Sanitizer ${_sanitizer_flags} added to ${_target}")
endif()
endif()
endfunction()
function(add_pch_to_target _target _pch_header)
if(COMMAND target_precompile_headers)
target_precompile_headers(${_target} PRIVATE ${_pch_header})
if(NOT MSVC)
set_source_files_properties(src/util.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
endif()
endif()
endfunction()
if(BIICODE)
include(biicode/cmake/biicode.cmake)
return()
endif()
include_directories(include)
include_directories(grpc)
if(FLATBUFFERS_BUILD_FLATLIB)
add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
# Attach header directory for when build via add_subdirectory().
target_include_directories(flatbuffers INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_compile_options(flatbuffers PRIVATE "${FLATBUFFERS_PRIVATE_CXX_FLAGS}")
if(FLATBUFFERS_ENABLE_PCH)
add_pch_to_target(flatbuffers include/flatbuffers/pch/pch.h)
endif()
endif()
if(FLATBUFFERS_BUILD_FLATC)
add_executable(flatc ${FlatBuffers_Compiler_SRCS})
if(FLATBUFFERS_ENABLE_PCH)
add_pch_to_target(flatc include/flatbuffers/pch/flatc_pch.h)
endif()
target_compile_options(flatc PRIVATE "${FLATBUFFERS_PRIVATE_CXX_FLAGS}")
if(FLATBUFFERS_CODE_SANITIZE AND NOT WIN32)
add_fsanitize_to_target(flatc ${FLATBUFFERS_CODE_SANITIZE})
endif()
if(NOT FLATBUFFERS_FLATC_EXECUTABLE)
set(FLATBUFFERS_FLATC_EXECUTABLE $<TARGET_FILE:flatc>)
endif()
if(MSVC)
# Make flatc.exe not depend on runtime dlls for easy distribution.
target_compile_options(flatc PUBLIC $<$<CONFIG:Release>:/MT>)
endif()
if(FLATBUFFERS_STATIC_FLATC AND NOT MSVC)
target_link_libraries(flatc PRIVATE -static)
endif()
endif()
if(FLATBUFFERS_BUILD_FLATHASH)
add_executable(flathash ${FlatHash_SRCS})
endif()
if(FLATBUFFERS_BUILD_SHAREDLIB)
add_library(flatbuffers_shared SHARED ${FlatBuffers_Library_SRCS})
# Shared object version: "major.minor.micro"
# - micro updated every release when there is no API/ABI changes
# - minor updated when there are additions in API/ABI
# - major (ABI number) updated when there are changes in ABI (or removals)
set(FlatBuffers_Library_SONAME_MAJOR ${VERSION_MAJOR})
set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers
SOVERSION "${FlatBuffers_Library_SONAME_MAJOR}"
VERSION "${FlatBuffers_Library_SONAME_FULL}")
if(FLATBUFFERS_ENABLE_PCH)
add_pch_to_target(flatbuffers_shared include/flatbuffers/pch/pch.h)
endif()
endif()
# Global list of generated files.
# Use the global property to be independent of PARENT_SCOPE.
set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
function(get_generated_output generated_files)
get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
set(${generated_files} ${tmp} PARENT_SCOPE)
endfunction(get_generated_output)
function(register_generated_output file_name)
get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
list(APPEND tmp ${file_name})
set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS ${tmp})
endfunction(register_generated_output)
function(compile_flatbuffers_schema_to_cpp_opt SRC_FBS OPT)
if(FLATBUFFERS_BUILD_LEGACY)
set(OPT ${OPT};--cpp-std c++0x)
else()
# --cpp-std is defined by flatc default settings.
endif()
message(STATUS "`${SRC_FBS}`: add generation of C++ code with '${OPT}'")
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
add_custom_command(
OUTPUT ${GEN_HEADER}
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
--cpp --gen-mutable --gen-object-api --reflect-names
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
${OPT}
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
-o "${SRC_FBS_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
DEPENDS flatc
COMMENT "Run generation: '${GEN_HEADER}'")
register_generated_output(${GEN_HEADER})
endfunction()
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
compile_flatbuffers_schema_to_cpp_opt(${SRC_FBS} "--no-includes;--gen-compare")
endfunction()
function(compile_flatbuffers_schema_to_binary SRC_FBS)
message(STATUS "`${SRC_FBS}`: add generation of binary (.bfbs) schema")
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
string(REGEX REPLACE "\\.fbs$" ".bfbs" GEN_BINARY_SCHEMA ${SRC_FBS})
# For details about flags see generate_code.py
add_custom_command(
OUTPUT ${GEN_BINARY_SCHEMA}
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
-b --schema --bfbs-comments --bfbs-builtins
--bfbs-filenames ${SRC_FBS_DIR}
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
-o "${SRC_FBS_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
DEPENDS flatc
COMMENT "Run generation: '${GEN_BINARY_SCHEMA}'")
register_generated_output(${GEN_BINARY_SCHEMA})
endfunction()
function(compile_flatbuffers_schema_to_embedded_binary SRC_FBS OPT)
if(FLATBUFFERS_BUILD_LEGACY)
set(OPT ${OPT};--cpp-std c++0x)
else()
# --cpp-std is defined by flatc default settings.
endif()
message(STATUS "`${SRC_FBS}`: add generation of C++ embedded binary schema code with '${OPT}'")
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
string(REGEX REPLACE "\\.fbs$" "_bfbs_generated.h" GEN_BFBS_HEADER ${SRC_FBS})
# For details about flags see generate_code.py
add_custom_command(
OUTPUT ${GEN_BFBS_HEADER}
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
--cpp --gen-mutable --gen-object-api --reflect-names
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
${OPT}
--bfbs-comments --bfbs-builtins --bfbs-gen-embed
--bfbs-filenames ${SRC_FBS_DIR}
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
-o "${SRC_FBS_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
DEPENDS flatc
COMMENT "Run generation: '${GEN_BFBS_HEADER}'")
register_generated_output(${GEN_BFBS_HEADER})
endfunction()
# Look if we have python 3.5 installed so that we can run the generate code
# python script after flatc is built.
find_package(PythonInterp 3.5)
if(PYTHONINTERP_FOUND AND
# Skip doing this if the MSVC version is below VS 12.
# https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html
(NOT MSVC OR MSVC_VERSION GREATER 1800))
set(GENERATION_SCRIPT ${PYTHON_EXECUTABLE} scripts/generate_code.py)
if(FLATBUFFERS_BUILD_LEGACY)
# Need to set --cpp-std c++-0x options
set(GENERATION_SCRIPT ${GENERATION_SCRIPT} --cpp-0x)
endif()
if(FLATBUFFERS_SKIP_MONSTER_EXTRA)
set(GENERATION_SCRIPT ${GENERATION_SCRIPT} --skip-monster-extra)
endif()
add_custom_command(
TARGET flatc
POST_BUILD
COMMAND ${GENERATION_SCRIPT} --flatc "${FLATBUFFERS_FLATC_EXECUTABLE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Running ${GENERATION_SCRIPT}..."
VERBATIM)
else()
message("No Python3 interpreter found! Unable to generate files automatically.")
endif()
if(FLATBUFFERS_BUILD_TESTS)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/samples" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
# TODO Add (monster_test.fbs monsterdata_test.json)->monsterdata_test.mon
compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
compile_flatbuffers_schema_to_binary(tests/monster_test.fbs)
compile_flatbuffers_schema_to_cpp_opt(tests/namespace_test/namespace_test1.fbs "--no-includes;--gen-compare;--gen-name-strings")
compile_flatbuffers_schema_to_cpp_opt(tests/namespace_test/namespace_test2.fbs "--no-includes;--gen-compare;--gen-name-strings")
compile_flatbuffers_schema_to_cpp_opt(tests/union_vector/union_vector.fbs "--no-includes;--gen-compare;--gen-name-strings")
compile_flatbuffers_schema_to_cpp(tests/optional_scalars.fbs)
compile_flatbuffers_schema_to_cpp_opt(tests/native_type_test.fbs "")
compile_flatbuffers_schema_to_cpp_opt(tests/arrays_test.fbs "--scoped-enums;--gen-compare")
compile_flatbuffers_schema_to_binary(tests/arrays_test.fbs)
compile_flatbuffers_schema_to_embedded_binary(tests/monster_test.fbs "--no-includes;--gen-compare")
if(NOT (MSVC AND (MSVC_VERSION LESS 1900)))
compile_flatbuffers_schema_to_cpp(tests/monster_extra.fbs) # Test floating-point NAN/INF.
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
add_executable(flattests ${FlatBuffers_Tests_SRCS})
add_dependencies(flattests generated_code)
set_property(TARGET flattests
PROPERTY COMPILE_DEFINITIONS FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1)
if(FLATBUFFERS_CODE_SANITIZE)
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
endif()
compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
compile_flatbuffers_schema_to_binary(samples/monster.fbs)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
add_executable(flatsamplebinary ${FlatBuffers_Sample_Binary_SRCS})
add_dependencies(flatsamplebinary generated_code)
add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
add_dependencies(flatsampletext generated_code)
add_executable(flatsamplebfbs ${FlatBuffers_Sample_BFBS_SRCS})
add_dependencies(flatsamplebfbs generated_code)
if(FLATBUFFERS_BUILD_CPP17)
# Don't generate header for flattests_cpp17 target.
# This target uses "generated_cpp17/monster_test_generated.h"
# produced by direct call of generate_code.py script.
add_executable(flattests_cpp17 ${FlatBuffers_Tests_CPP17_SRCS})
add_dependencies(flattests_cpp17 generated_code)
target_compile_features(flattests_cpp17 PRIVATE cxx_std_17)
target_compile_definitions(flattests_cpp17 PRIVATE
FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1
)
if(FLATBUFFERS_CODE_SANITIZE)
add_fsanitize_to_target(flattests_cpp17 ${FLATBUFFERS_CODE_SANITIZE})
endif()
endif(FLATBUFFERS_BUILD_CPP17)
endif()
if(FLATBUFFERS_BUILD_GRPCTEST)
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-shadow")
endif()
if(NOT GRPC_INSTALL_PATH)
message(SEND_ERROR "GRPC_INSTALL_PATH variable is not defined. See grpc/README.md")
endif()
if(NOT PROTOBUF_DOWNLOAD_PATH)
message(SEND_ERROR "PROTOBUF_DOWNLOAD_PATH variable is not defined. See grpc/README.md")
endif()
INCLUDE_DIRECTORIES(${GRPC_INSTALL_PATH}/include)
INCLUDE_DIRECTORIES(${PROTOBUF_DOWNLOAD_PATH}/src)
find_package(Threads REQUIRED)
list(APPEND CMAKE_PREFIX_PATH ${GRPC_INSTALL_PATH})
find_package(absl CONFIG REQUIRED)
find_package(protobuf CONFIG REQUIRED)
find_package(gRPC CONFIG REQUIRED)
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
add_dependencies(grpctest generated_code)
target_link_libraries(grpctest PRIVATE gRPC::grpc++_unsecure gRPC::grpc_unsecure gRPC::gpr pthread dl)
if(FLATBUFFERS_CODE_SANITIZE AND NOT WIN32)
# GRPC test has problems with alignment and will fail under ASAN/UBSAN.
# add_fsanitize_to_target(grpctest ${FLATBUFFERS_CODE_SANITIZE})
endif()
endif()
if(FLATBUFFERS_INSTALL)
include(GNUInstallDirs)
install(DIRECTORY include/flatbuffers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
set(FB_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/flatbuffers")
configure_file(CMake/FlatbuffersConfigVersion.cmake.in FlatbuffersConfigVersion.cmake @ONLY)
install(
FILES "CMake/FlatbuffersConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/FlatbuffersConfigVersion.cmake"
DESTINATION ${FB_CMAKE_DIR}
)
if(FLATBUFFERS_BUILD_FLATLIB)
if(CMAKE_VERSION VERSION_LESS 3.0)
install(
TARGETS flatbuffers EXPORT FlatbuffersTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
else()
install(
TARGETS flatbuffers EXPORT FlatbuffersTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif()
install(EXPORT FlatbuffersTargets
FILE FlatbuffersTargets.cmake
NAMESPACE flatbuffers::
DESTINATION ${FB_CMAKE_DIR}
)
endif()
if(FLATBUFFERS_BUILD_FLATC)
install(
TARGETS flatc EXPORT FlatcTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(
EXPORT FlatcTargets
FILE FlatcTargets.cmake
NAMESPACE flatbuffers::
DESTINATION ${FB_CMAKE_DIR}
)
endif()
if(FLATBUFFERS_BUILD_SHAREDLIB)
if(CMAKE_VERSION VERSION_LESS 3.0)
install(
TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
else()
install(
TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif()
install(
EXPORT FlatbuffersSharedTargets
FILE FlatbuffersSharedTargets.cmake
NAMESPACE flatbuffers::
DESTINATION ${FB_CMAKE_DIR}
)
endif()
if(FLATBUFFERS_BUILD_SHAREDLIB OR FLATBUFFERS_BUILD_FLATLIB)
configure_file(CMake/flatbuffers.pc.in flatbuffers.pc @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
endif()
endif()
if(FLATBUFFERS_BUILD_TESTS)
enable_testing()
add_test(NAME flattests COMMAND flattests)
if(FLATBUFFERS_BUILD_CPP17)
add_test(NAME flattests_cpp17 COMMAND flattests_cpp17)
endif()
if(FLATBUFFERS_BUILD_GRPCTEST)
add_test(NAME grpctest COMMAND grpctest)
endif()
endif()
# This target is sync-barrier.
# Other generate-dependent targets can depend on 'generated_code' only.
get_generated_output(fbs_generated)
if(fbs_generated)
# message(STATUS "Add generated_code target with files:${fbs_generated}")
add_custom_target(generated_code
DEPENDS ${fbs_generated}
COMMENT "All generated files were updated.")
endif()
include(CMake/BuildFlatBuffers.cmake)
if(UNIX)
# Use of CPack only supported on Linux systems.
if(FLATBUFFERS_PACKAGE_DEBIAN)
include(CMake/PackageDebian.cmake)
include(CPack)
endif()
if (FLATBUFFERS_PACKAGE_REDHAT)
include(CMake/PackageRedhat.cmake)
include(CPack)
endif()
endif()
# Include for running Google Benchmarks.
if(FLATBUFFERS_BUILD_BENCHMARKS AND CMAKE_VERSION VERSION_GREATER 3.13)
add_subdirectory(benchmarks)
endif()
# Add FlatBuffers::FlatBuffers interface, needed for FetchContent_Declare
add_library(FlatBuffers INTERFACE)
add_library(FlatBuffers::FlatBuffers ALIAS FlatBuffers)
target_include_directories(
FlatBuffers
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/include>)

View File

@@ -1,10 +1,10 @@
set(VERSION_MAJOR 2)
set(VERSION_MINOR 0)
set(VERSION_PATCH 5)
set(VERSION_PATCH 6)
set(VERSION_COMMIT 0)
find_program(GIT git)
if(GIT)
if(GIT AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
execute_process(
COMMAND ${GIT} describe --tags
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}

View File

@@ -1,5 +1,20 @@
# This is the legacy minimum version flatbuffers supported for a while.
cmake_minimum_required(VERSION 2.8.12)
# CMake version 3.16 is the 'de-facto' minimum version for flatbuffers. If the
# current cmake is older than this, warn the user and include the legacy file to
# provide some level of support.
if(CMAKE_VERSION VERSION_LESS 3.16)
message(WARNING "Using cmake version ${CMAKE_VERSION} which is older than "
"our target version of 3.16. This will use the legacy CMakeLists.txt that "
"supports version 2.8.12 and higher, but not actively maintained. Consider "
"upgrading cmake to a newer version, as this may become a fatal error in the "
"future.")
# Use the legacy version of CMakeLists.txt
include(CMake/CMakeLists_legacy.cmake.in)
return()
endif()
if (POLICY CMP0048)
cmake_policy(SET CMP0048 NEW)
project(FlatBuffers
@@ -59,6 +74,9 @@ option(FLATBUFFERS_ENABLE_PCH
option(FLATBUFFERS_SKIP_MONSTER_EXTRA
"Skip generating monster_extra.fbs that contains non-supported numerical\"
types." OFF)
option(FLATBUFFERS_OSX_BUILD_UNIVERSAL
"Enable the build for multiple architectures on OS X (arm64, x86_64)."
ON)
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
message(WARNING
@@ -280,10 +298,26 @@ elseif(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -fsigned-char")
# MSVC **MUST** come before the Clang check, as clang-cl is flagged by CMake as "MSVC", but it still textually
# matches as Clang in its Compiler Id :)
# Note: in CMake >= 3.14 we can check CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" or "MSVC" to differentiate...
elseif(MSVC)
# Visual Studio pedantic build settings
# warning C4512: assignment operator could not be generated
# warning C4316: object allocated on the heap may not be aligned
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /wd4512 /wd4316")
if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_WARNINGS")
endif()
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
if(APPLE)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if(FLATBUFFERS_OSX_BUILD_UNIVERSAL)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
endif()
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
endif()
@@ -310,14 +344,6 @@ elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -fsigned-char")
elseif(MSVC)
# Visual Studio pedantic build settings
# warning C4512: assignment operator could not be generated
# warning C4316: object allocated on the heap may not be aligned
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /wd4512 /wd4316")
# multi-core build.
add_definitions("/MP")
endif()
# Append FLATBUFFERS_CXX_FLAGS to CMAKE_CXX_FLAGS.
@@ -368,11 +394,6 @@ function(add_pch_to_target _target _pch_header)
endif()
endfunction()
if(BIICODE)
include(biicode/cmake/biicode.cmake)
return()
endif()
include_directories(include)
include_directories(grpc)
@@ -515,32 +536,25 @@ function(compile_flatbuffers_schema_to_embedded_binary SRC_FBS OPT)
register_generated_output(${GEN_BFBS_HEADER})
endfunction()
# Look if we have python 3 installed so that we can run the generate code python
# script after flatc is built.
find_package(PythonInterp 3)
# Look if we have python 3.5 installed so that we can run the generate code
# python script after flatc is built.
find_package(Python3 3.5 COMPONENTS Interpreter)
if(PYTHONINTERP_FOUND AND
# Skip doing this if the MSVC version is below VS 12.
# https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html
(NOT MSVC OR MSVC_VERSION GREATER 1800))
if(WIN32)
set(GENERATION_SCRIPT py scripts/generate_code.py)
else()
set(GENERATION_SCRIPT scripts/generate_code.py)
endif()
if(Python3_Interpreter_FOUND)
set(GENERATION_OPTS --flatc "${FLATBUFFERS_FLATC_EXECUTABLE}")
if(FLATBUFFERS_BUILD_LEGACY)
# Need to set --cpp-std c++-0x options
set(GENERATION_SCRIPT ${GENERATION_SCRIPT} --cpp-0x)
set(GENERATION_OPTS ${GENERATION_OPTS}--cpp-0x)
endif()
if(FLATBUFFERS_SKIP_MONSTER_EXTRA)
set(GENERATION_SCRIPT ${GENERATION_SCRIPT} --skip-monster-extra)
set(GENERATION_OPTS ${GENERATION_OPTS} --skip-monster-extra)
endif()
add_custom_command(
TARGET flatc
POST_BUILD
COMMAND ${GENERATION_SCRIPT} --flatc "${FLATBUFFERS_FLATC_EXECUTABLE}"
COMMAND ${Python3_EXECUTABLE} scripts/generate_code.py ${GENERATION_OPTS} --skip-gen-reflection
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Running ${GENERATION_SCRIPT}..."
COMMENT "Running scripts/generate_code.py..."
VERBATIM)
else()
message("No Python3 interpreter found! Unable to generate files automatically.")
@@ -642,18 +656,11 @@ if(FLATBUFFERS_INSTALL)
)
if(FLATBUFFERS_BUILD_FLATLIB)
if(CMAKE_VERSION VERSION_LESS 3.0)
install(
TARGETS flatbuffers EXPORT FlatbuffersTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
else()
install(
TARGETS flatbuffers EXPORT FlatbuffersTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif()
install(
TARGETS flatbuffers EXPORT FlatbuffersTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(EXPORT FlatbuffersTargets
FILE FlatbuffersTargets.cmake
@@ -677,24 +684,15 @@ if(FLATBUFFERS_INSTALL)
endif()
if(FLATBUFFERS_BUILD_SHAREDLIB)
if(CMAKE_VERSION VERSION_LESS 3.0)
install(
TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
else()
install(
TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif()
install(
TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
install(
EXPORT FlatbuffersSharedTargets
FILE FlatbuffersSharedTargets.cmake
NAMESPACE flatbuffers::
@@ -748,6 +746,14 @@ if(UNIX)
endif()
# Include for running Google Benchmarks.
if(FLATBUFFERS_BUILD_BENCHMARKS AND CMAKE_VERSION VERSION_GREATER 3.13)
if(FLATBUFFERS_BUILD_BENCHMARKS)
add_subdirectory(benchmarks)
endif()
endif()
# Add FlatBuffers::FlatBuffers interface, needed for FetchContent_Declare
add_library(FlatBuffers INTERFACE)
add_library(FlatBuffers::FlatBuffers ALIAS FlatBuffers)
target_include_directories(
FlatBuffers
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/include>)

View File

@@ -29,7 +29,7 @@ http_archive(
)
##### GRPC
_GRPC_VERSION = "1.39.0"
_GRPC_VERSION = "1.42.0"
http_archive(
name = "com_github_grpc_grpc",

View File

@@ -1,20 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2013 Google, Inc.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.FlatBufferTest">

View File

@@ -1,76 +0,0 @@
branches:
only:
- master
environment:
nodejs_version: "14"
global:
# Workaround for https://github.com/conda/conda-build/issues/636
PYTHONIOENCODING: UTF-8
CONDA_INSTALL_LOCN: "C:\\Miniconda35-x64"
CMAKE_OPTIONS: ""
CPP_TEST_OPTIONS: ""
CHECK_GEN_CODE: 1
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_VS_VERSION: "14 2015"
platform:
- x86
- x64
configuration:
- Debug
- Release
before_build:
- cmake . -G"Visual Studio %CMAKE_VS_VERSION%" -DFLATBUFFERS_CODE_SANITIZE=1 %CMAKE_OPTIONS%
# This cuts down on a lot of noise generated by xamarin warnings.
- if exist "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
build:
project: ALL_BUILD.vcxproj
verbosity: minimal
after_build:
- python conan/appveyor/install.py
- python conan/appveyor/build.py
install:
- set PATH=%CONDA_INSTALL_LOCN%;%CONDA_INSTALL_LOCN%\scripts;%PATH%;
- ps: Install-Product node $env:nodejs_version
test_script:
- if [%CHECK_GEN_CODE%]==[1] (call py scripts/check_generate_code.py "%CPP_TEST_OPTIONS%")
- "cd tests"
- 7z a GeneratedMyGameCode.zip MyGame\
- rem "---------------- C++ -----------------"
- "cd .."
- "%CONFIGURATION%\\flattests.exe"
- rem "---------------- JS -----------------"
- "node --version"
- "npm install"
- "npm run compile"
- "cd tests"
- "TypeScriptTest.bat"
- rem "---------------- C# -----------------"
# Have to compile this here rather than in "build" above because AppVeyor only
# supports building one project??
- "cd FlatBuffers.Test"
- "dotnet new sln"
- "dotnet sln add FlatBuffers.Test.csproj"
- "nuget restore"
- "mkdir .tmp"
- "msbuild.exe /property:Configuration=Release;OutputPath=.tmp /verbosity:minimal FlatBuffers.Test.csproj"
- ".tmp\\FlatBuffers.Test.exe"
# Run tests with UNSAFE_BYTEBUFFER
- "msbuild.exe /property:Configuration=Release;UnsafeByteBuffer=true;OutputPath=.tmp /verbosity:minimal FlatBuffers.Test.csproj"
- ".tmp\\FlatBuffers.Test.exe"
artifacts:
- path: $(CONFIGURATION)\flatc.exe
name: flatc.exe
- path: tests\GeneratedMyGameCode.zip
name: GeneratedMyGameCode.zip

View File

@@ -6,16 +6,6 @@ import subprocess
from cpt.packager import ConanMultiPackager
def set_appveyor_environment():
if os.getenv("APPVEYOR") is not None:
compiler_version = os.getenv("CMAKE_VS_VERSION").split(" ")[0].replace('"', '')
os.environ["CONAN_VISUAL_VERSIONS"] = compiler_version
os.environ["CONAN_STABLE_BRANCH_PATTERN"] = "master"
ci_platform = os.getenv("Platform").replace('"', '')
ci_platform = "x86" if ci_platform == "x86" else "x86_64"
os.environ["CONAN_ARCHS"] = ci_platform
os.environ["CONAN_BUILD_TYPES"] = os.getenv("Configuration").replace('"', '')
def get_branch():
try:
@@ -56,7 +46,6 @@ if __name__ == "__main__":
stable_branch_pattern = os.getenv("CONAN_STABLE_BRANCH_PATTERN", r"v\d+\.\d+\.\d+.*")
test_folder = os.getenv("CPT_TEST_FOLDER", os.path.join("conan", "test_package"))
upload_only_when_stable = os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", True)
set_appveyor_environment()
builder = ConanMultiPackager(reference=get_reference(username),
username=username,

View File

@@ -1,4 +1,4 @@
## 2.0.0
## 2.0.5
- switch to null safety (#6696)
- add Object APIs (pack/unpack) (#6682, #6723, #6846)

View File

@@ -1,35 +1,3 @@
The code in lib/flat_buffers.dart is based on code that was releases under the
following license:
Copyright 2012, the Dart project authors. 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.
To the extent permissible, the changes to that code and the other assets in
this package are licensed under the Apache2 license:
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

View File

@@ -2,10 +2,8 @@
This package is used to read and write [FlatBuffers](https://google.github.io/flatbuffers/).
Most consumers will want to use the [`flatc` - FlatBuffer compiler](https://github.com/google/flatbuffers) binary for your platform:
* [Linux](https://github.com/google/flatbuffers/suites/4363603985/artifacts/114682272)
* [macOS](https://github.com/google/flatbuffers/suites/4363603985/artifacts/114682273)
* [Windows](https://github.com/google/flatbuffers/suites/4363603985/artifacts/114682274)
Most consumers will want to use the [`flatc` - FlatBuffer compiler](https://github.com/google/flatbuffers) binary for your platform.
You can find it in the `generator/{Platform}` directory of the [released package archive](https://pub.dev/packages/flat_buffers/versions/2.0.5.tar.gz).
The FlatBuffer compiler `flatc` reads a FlatBuffers IDL schema and generates Dart code.
The generated classes can be used to read or write binary data/files that are interoperable with
@@ -14,4 +12,12 @@ examples folder.
For more details and documentation, head over to the official site and read the
[Tutorial](https://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html) and how to
[use FlatBuffers in Dart](https://google.github.io/flatbuffers/flatbuffers_guide_use_dart.html).
[use FlatBuffers in Dart](https://google.github.io/flatbuffers/flatbuffers_guide_use_dart.html).
## Dart 2.0 notes
Version 2.0.5 ships with it's own custom build of `flatc` because this is an extraordinary release to catch-up
with FlatBuffers for other platforms. This generator can only generate dart code (to avoid generating code for other platforms which isn't released yet).
On the other hand, the generated code still produces standard binary FlatBuffers compatible with other languages.
In other words: only `flatc --dart ...` works with this generator, but your app will be able to produce and read standard binary (`Uint8List`) FlatBuffers that are fully compotible with other languages supporting FlatBuffers (e.g. Java, C++, ...).
In the future a common `flatc` binary for all platforms would be shipped through GitHub release page instead.

View File

@@ -308,7 +308,7 @@ class Builder {
assert(_inVTable);
// Prepare for writing the VTable.
_prepare(_sizeofInt32, 1);
int tableTail = _tail;
var tableTail = _tail;
// Prepare the size of the current table.
final currentVTable = _currentVTable!;
currentVTable.tableSize = tableTail - _currentTableEndTail;
@@ -320,10 +320,10 @@ class Builder {
// Try to find an existing compatible VTable.
if (deduplicateTables) {
// Search backward - more likely to have recently used one
for (int i = _vTables.length - 1; i >= 0; i--) {
final int vt2Offset = _vTables[i];
final int vt2Start = _buf.lengthInBytes - vt2Offset;
final int vt2Size = _buf.getUint16(vt2Start, Endian.little);
for (var i = _vTables.length - 1; i >= 0; i--) {
final vt2Offset = _vTables[i];
final vt2Start = _buf.lengthInBytes - vt2Offset;
final vt2Size = _buf.getUint16(vt2Start, Endian.little);
if (currentVTable._vTableSize == vt2Size &&
currentVTable._offsetsMatch(vt2Start, _buf)) {
@@ -370,7 +370,7 @@ class Builder {
final finishedSize = size();
_setUint32AtTail(finishedSize, finishedSize - offset);
if (fileIdentifier != null) {
for (int i = 0; i < 4; i++) {
for (var i = 0; i < 4; i++) {
_setUint8AtTail(
finishedSize - _sizeofUint32 - i, fileIdentifier.codeUnitAt(i));
}
@@ -495,7 +495,7 @@ class Builder {
/// Writes a list of Structs to the buffer, returning the offset
int writeListOfStructs(List<ObjectBuilder> structBuilders) {
assert(!_inVTable);
for (int i = structBuilders.length - 1; i >= 0; i--) {
for (var i = structBuilders.length - 1; i >= 0; i--) {
structBuilders[i].finish(this);
}
return endStructVector(structBuilders.length);
@@ -505,11 +505,11 @@ class Builder {
int writeList(List<int> values) {
assert(!_inVTable);
_prepare(_sizeofUint32, 1 + values.length);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (int value in values) {
for (var value in values) {
_setUint32AtTail(tail, tail - value);
tail -= _sizeofUint32;
}
@@ -520,11 +520,11 @@ class Builder {
int writeListFloat64(List<double> values) {
assert(!_inVTable);
_prepare(_sizeofFloat64, values.length, additionalBytes: _sizeofUint32);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (double value in values) {
for (var value in values) {
_setFloat64AtTail(tail, value);
tail -= _sizeofFloat64;
}
@@ -535,11 +535,11 @@ class Builder {
int writeListFloat32(List<double> values) {
assert(!_inVTable);
_prepare(_sizeofFloat32, 1 + values.length);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (double value in values) {
for (var value in values) {
_setFloat32AtTail(tail, value);
tail -= _sizeofFloat32;
}
@@ -550,11 +550,11 @@ class Builder {
int writeListInt64(List<int> values) {
assert(!_inVTable);
_prepare(_sizeofInt64, values.length, additionalBytes: _sizeofUint32);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (int value in values) {
for (var value in values) {
_setInt64AtTail(tail, value);
tail -= _sizeofInt64;
}
@@ -565,11 +565,11 @@ class Builder {
int writeListUint64(List<int> values) {
assert(!_inVTable);
_prepare(_sizeofUint64, values.length, additionalBytes: _sizeofUint32);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (int value in values) {
for (var value in values) {
_setUint64AtTail(tail, value);
tail -= _sizeofUint64;
}
@@ -580,11 +580,11 @@ class Builder {
int writeListInt32(List<int> values) {
assert(!_inVTable);
_prepare(_sizeofUint32, 1 + values.length);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (int value in values) {
for (var value in values) {
_setInt32AtTail(tail, value);
tail -= _sizeofInt32;
}
@@ -595,11 +595,11 @@ class Builder {
int writeListUint32(List<int> values) {
assert(!_inVTable);
_prepare(_sizeofUint32, 1 + values.length);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (int value in values) {
for (var value in values) {
_setUint32AtTail(tail, value);
tail -= _sizeofUint32;
}
@@ -610,11 +610,11 @@ class Builder {
int writeListInt16(List<int> values) {
assert(!_inVTable);
_prepare(_sizeofUint32, 1, additionalBytes: 2 * values.length);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (int value in values) {
for (var value in values) {
_setInt16AtTail(tail, value);
tail -= _sizeofInt16;
}
@@ -625,11 +625,11 @@ class Builder {
int writeListUint16(List<int> values) {
assert(!_inVTable);
_prepare(_sizeofUint32, 1, additionalBytes: 2 * values.length);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (int value in values) {
for (var value in values) {
_setUint16AtTail(tail, value);
tail -= _sizeofUint16;
}
@@ -645,11 +645,11 @@ class Builder {
int writeListInt8(List<int> values) {
assert(!_inVTable);
_prepare(_sizeofUint32, 1, additionalBytes: values.length);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (int value in values) {
for (var value in values) {
_setInt8AtTail(tail, value);
tail -= _sizeofUint8;
}
@@ -660,11 +660,11 @@ class Builder {
int writeListUint8(List<int> values) {
assert(!_inVTable);
_prepare(_sizeofUint32, 1, additionalBytes: values.length);
final int result = _tail;
int tail = _tail;
final result = _tail;
var tail = _tail;
_setUint32AtTail(tail, values.length);
tail -= _sizeofUint32;
for (int value in values) {
for (var value in values) {
_setUint8AtTail(tail, value);
tail -= _sizeofUint8;
}
@@ -729,7 +729,7 @@ class Builder {
_prepare(4, 1, additionalBytes: length + 1);
_setUint32AtTail(_tail, length);
var offset = _buf.lengthInBytes - _tail + 4;
for (int i = 0; i < length; i++) {
for (var i = 0; i < length; i++) {
_buf.setUint8(offset++, bytes[i]);
}
_buf.setUint8(offset, 0); // trailing zero
@@ -756,7 +756,7 @@ class Builder {
/// Zero-pads the buffer, which may be required for some struct layouts.
@pragma('vm:prefer-inline')
void pad(int howManyBytes) {
for (int i = 0; i < howManyBytes; i++) {
for (var i = 0; i < howManyBytes; i++) {
putUint8(0);
}
}
@@ -772,17 +772,17 @@ class Builder {
_maxAlign = size;
}
// Prepare amount of required space.
int dataSize = size * count + additionalBytes;
int alignDelta = (-(_tail + dataSize)) & (size - 1);
int bufSize = alignDelta + dataSize;
var dataSize = size * count + additionalBytes;
var alignDelta = (-(_tail + dataSize)) & (size - 1);
var bufSize = alignDelta + dataSize;
// Ensure that we have the required amount of space.
{
int oldCapacity = _buf.lengthInBytes;
var oldCapacity = _buf.lengthInBytes;
if (_tail + bufSize > oldCapacity) {
int desiredNewCapacity = (oldCapacity + bufSize) * 2;
int deltaCapacity = desiredNewCapacity - oldCapacity;
var desiredNewCapacity = (oldCapacity + bufSize) * 2;
var deltaCapacity = desiredNewCapacity - oldCapacity;
deltaCapacity += (-deltaCapacity) & (_maxAlign - 1);
int newCapacity = oldCapacity + deltaCapacity;
var newCapacity = oldCapacity + deltaCapacity;
_buf = _allocator.resize(_buf, newCapacity, _tail, 0);
}
}
@@ -1018,22 +1018,22 @@ abstract class Reader<T> {
/// Read the value of the given [field] in the given [object].
@pragma('vm:prefer-inline')
T vTableGet(BufferContext object, int offset, int field, T defaultValue) {
int fieldOffset = _vTableFieldOffset(object, offset, field);
var fieldOffset = _vTableFieldOffset(object, offset, field);
return fieldOffset == 0 ? defaultValue : read(object, offset + fieldOffset);
}
/// Read the value of the given [field] in the given [object].
@pragma('vm:prefer-inline')
T? vTableGetNullable(BufferContext object, int offset, int field) {
int fieldOffset = _vTableFieldOffset(object, offset, field);
var fieldOffset = _vTableFieldOffset(object, offset, field);
return fieldOffset == 0 ? null : read(object, offset + fieldOffset);
}
@pragma('vm:prefer-inline')
int _vTableFieldOffset(BufferContext object, int offset, int field) {
int vTableSOffset = object._getInt32(offset);
int vTableOffset = offset - vTableSOffset;
int vTableSize = object._getUint16(vTableOffset);
var vTableSOffset = object._getInt32(offset);
var vTableOffset = offset - vTableSOffset;
var vTableSize = object._getUint16(vTableOffset);
if (field >= vTableSize) return 0;
return object._getUint16(vTableOffset + field);
}
@@ -1052,9 +1052,9 @@ class StringReader extends Reader<String> {
@override
@pragma('vm:prefer-inline')
String read(BufferContext bc, int offset) {
int strOffset = bc.derefObject(offset);
int length = bc._getUint32(strOffset);
Uint8List bytes = bc._asUint8List(strOffset + _sizeofUint32, length);
var strOffset = bc.derefObject(offset);
var length = bc._getUint32(strOffset);
var bytes = bc._asUint8List(strOffset + _sizeofUint32, length);
if (asciiOptimization && _isLatin(bytes)) {
return String.fromCharCodes(bytes);
}
@@ -1063,8 +1063,8 @@ class StringReader extends Reader<String> {
@pragma('vm:prefer-inline')
static bool _isLatin(Uint8List bytes) {
int length = bytes.length;
for (int i = 0; i < length; i++) {
var length = bytes.length;
for (var i = 0; i < length; i++) {
if (bytes[i] > 127) {
return false;
}
@@ -1099,7 +1099,7 @@ abstract class TableReader<T> extends Reader<T> {
@override
T read(BufferContext bc, int offset) {
int objectOffset = bc.derefObject(offset);
var objectOffset = bc.derefObject(offset);
return createObject(bc, objectOffset);
}
}
@@ -1285,7 +1285,7 @@ class _FbGenericList<E> extends _FbList<E> {
@pragma('vm:prefer-inline')
E operator [](int i) {
_items ??= List<E?>.filled(length, null);
E? item = _items![i];
var item = _items![i];
if (item == null) {
item = elementReader.read(bc, offset + 4 + elementReader.size * i);
_items![i] = item;
@@ -1394,7 +1394,7 @@ class _VTable {
@pragma('vm:prefer-inline')
bool _offsetsMatch(int vt2Start, ByteData buf) {
assert(offsetsComputed);
for (int i = 0; i < numFields; i++) {
for (var i = 0; i < numFields; i++) {
if (fieldOffsets[i] !=
buf.getUint16(vt2Start + _metadataLength + (2 * i), Endian.little)) {
return false;
@@ -1427,7 +1427,7 @@ class _VTable {
buf.setUint16(bufOffset, tableSize, Endian.little);
bufOffset += 2;
// Field offsets.
for (int i = 0; i < numFields; i++) {
for (var i = 0; i < numFields; i++) {
buf.setUint16(bufOffset, fieldOffsets[i], Endian.little);
bufOffset += 2;
}

View File

@@ -1,5 +1,5 @@
name: flat_buffers
version: 2.0.0
version: 2.0.5
description: FlatBuffers reading and writing library for Dart. Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team.
homepage: https://github.com/google/flatbuffers
documentation: https://google.github.io/flatbuffers/index.html

View File

@@ -84,7 +84,8 @@ class CheckOtherLangaugesData {
'nonOwningReference: 0, vectorOfNonOwningReferences: null, '
'anyUniqueType: null, anyUnique: null, anyAmbiguousType: null, '
'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race{value: -1}, '
'testrequirednestedflatbuffer: null, scalarKeySortedTables: null}, '
'testrequirednestedflatbuffer: null, scalarKeySortedTables: null, '
'nativeInline: null}, '
'test4: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], '
'testarrayofstring: [test1, test2], testarrayoftables: null, '
'enemy: Monster{pos: null, mana: 150, hp: 100, name: Fred, '
@@ -104,7 +105,8 @@ class CheckOtherLangaugesData {
'nonOwningReference: 0, vectorOfNonOwningReferences: null, '
'anyUniqueType: null, anyUnique: null, anyAmbiguousType: null, '
'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race{value: -1}, '
'testrequirednestedflatbuffer: null, scalarKeySortedTables: null}, '
'testrequirednestedflatbuffer: null, scalarKeySortedTables: null, '
'nativeInline: null}, '
'testnestedflatbuffer: null, testempty: null, testbool: true, '
'testhashs32Fnv1: -579221183, testhashu32Fnv1: 3715746113, '
'testhashs64Fnv1: 7930699090847568257, '
@@ -128,7 +130,8 @@ class CheckOtherLangaugesData {
'anyAmbiguousType: null, '
'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race{value: -1}, '
'testrequirednestedflatbuffer: null, scalarKeySortedTables: [Stat{id: '
'miss, val: 0, count: 0}, Stat{id: hit, val: 10, count: 1}]}',
'miss, val: 0, count: 0}, Stat{id: hit, val: 10, count: 1}], '
'nativeInline: Test{a: 1, b: 2}}',
);
}
}

View File

@@ -121,14 +121,3 @@ add this directive:
set(FLATBUFFERS_MAX_PARSING_DEPTH 16)
```
to `CMakeLists.txt` file before `add_subdirectory(${FLATBUFFERS_SRC_DIR})` line.
#### For Google Play apps
For applications on Google Play that integrate this library, usage is tracked.
This tracking is done automatically using the embedded version string
(flatbuffer_version_string), and helps us continue to optimize it.
Aside from consuming a few extra bytes in your application binary, it shouldn't
affect your application at all. We use this information to let us know if
FlatBuffers is useful and if we should continue to invest in it. Since this is
open source, you are free to remove the version string but we would appreciate
if you would leave it in.

View File

@@ -101,7 +101,7 @@ Additional options:
- `--gen-mutable` : Generate additional non-const accessors for mutating
FlatBuffers in-place.
- `--gen-onefile` : Generate single output file for C# and Go.
- `--gen-onefile` : Generate single output file for C#, Go, and Python.
- `--gen-name-strings` : Generate type name functions for C++.
@@ -220,5 +220,9 @@ Additional options:
- `--cs-global-alias` : Prepend `global::` to all user generated csharp classes and structs.
- `--json-nested-bytes` : Allow a nested_flatbuffer field to be parsed as a
vector of bytes in JSON, which is unsafe unless checked by a verifier
afterwards.
NOTE: short-form options for generators are deprecated, use the long form
whenever possible.

View File

@@ -180,7 +180,8 @@ To use:
An additional feature of the object API is the ability to allow you to
serialize & deserialize a JSON text.
To use Json Serialization, add `--cs-gen-json-serializer` option to `flatc` and
add `Newtonsoft.Json` nuget package to csproj.
add `Newtonsoft.Json` nuget package to csproj. This requires explicitly setting
the `--gen-object-api` option as well.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
// Deserialize MonsterT from json
@@ -192,7 +193,7 @@ add `Newtonsoft.Json` nuget package to csproj.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Limitation
* `hash` attribute currentry not supported.
* `hash` attribute currently not supported.
* NuGet package Dependency
* [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json)

View File

@@ -3392,6 +3392,125 @@ decimals in the JSON document.*
## Advanced Features for Each Language
### Vector of Unions
Some languages support storing unions directly in a vector.
~~~
// File found in tests/union_vector/union_vector.fbs
namespace Example.VectorOfUnions;
// Demonstrates the ability to have vectors of unions, and also to
// store structs and strings in unions.
table Attacker {
sword_attack_damage: int;
}
struct Rapunzel {
hair_length: int;
}
struct BookReader {
books_read: int;
}
union Character {
MuLan: Attacker, // Can have name be different from type.
Rapunzel, // Or just both the same, as before.
Belle: BookReader,
BookFan: BookReader,
Other: string,
Unused: string
}
table Movie {
main_character: Character;
characters: [Character];
}
~~~
#### Creating
Analagously to how a union adds two fields to a table a vector of unions creates two different vectors:
one for the union data and one for the data types.
<div class="language-cpp">
C++ supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-typescript">
Typescript supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-php">
PHP supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-java">
Java supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-csharp">
~~~{.cs}
using FlatBuffers;
using Example.VectorOfUnions;
var fbb = new FlatBufferBuilder(100);
var characterTypes = new[]
{
Character.MuLan,
Character.Belle,
Character.Other,
};
var characterTypesOffset = Movie.CreateCharactersTypeVector(fbb, characterTypes);
var characters = new[]
{
Attacker.CreateAttacker(fbb, 10).Value,
BookReader.CreateBookReader(fbb, 20).Value,
fbb.CreateSharedString("Chip").Value,
};
var charactersOffset = Movie.CreateCharactersVector(fbb, characters);
var movieOffset = Movie.CreateMovie(
fbb,
Character.Rapunzel,
rapunzel,
characterTypesOffset,
charactersOffset);
Movie.FinishMovieBuffer(fbb, movieOffset);
~~~
</div>
<div class="language-kotlin">
Kotlin supports vectors of unions, but it isn't currently documented.
</div>
<div class="language-swift">
Swift supports vectors of unions, but it isn't currently documented.
</div>
#### Reading
<div class="language-csharp">
~~~{.cs}
var movie = Movie.GetRootAsMovie(fbb.DataBuffer);
for (var i = 0; i <= movie.CharactersLength; i++)
{
if (movie.CharactersType(i) == Character.MuLan)
{
var mulanSwordDamage = movie.Characters<Attacker>(i).Value.SwordAttackDamage;
}
else if (movie.CharactersType(i) == Character.Belle)
{
var belleBooksRead = movie.Characters<BookReader>(i).Value.BooksRead;
}
else if (movie.CharactersType(i) == Character.Other)
{
var otherStr = movie.CharactersAsString(i);
}
}
~~~
</div>
### Further Reading
Each language has a dedicated `Use in XXX` page in the Programmer's Guide
to cover the nuances of FlatBuffers in that language.

View File

@@ -4,11 +4,11 @@ LDFLAGS ?=
.PHONY: all
all: server client
greeter_generated.h: greeter.fbs
greeter_generated: greeter.fbs
flatc --grpc --cpp $<
server: server.cpp greeter.grpc.fb.cc greeter_generated.h greeter.grpc.fb.h
server: greeter_generated server.cpp greeter.grpc.fb.cc greeter.grpc.fb.h
g++ -std=c++11 -O2 $(CXXFLAGS) $(LDFLAGS) -lgpr -lgrpc -lgrpc++ server.cpp greeter.grpc.fb.cc -o $@
client: client.cpp greeter.grpc.fb.cc greeter_generated.h greeter.grpc.fb.h
client: greeter_generated client.cpp greeter.grpc.fb.cc greeter.grpc.fb.h
g++ -std=c++11 -O2 $(CXXFLAGS) $(LDFLAGS) -lgpr -lgrpc -lgrpc++ client.cpp greeter.grpc.fb.cc -o $@

View File

@@ -7,7 +7,6 @@ package(
filegroup(
name = "common_headers",
srcs = [
"config.h",
"schema_interface.h",
],
)

View File

@@ -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

View File

@@ -1,51 +1,17 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/compiler/cpp_generator.h"
#include <map>
#include "src/compiler/cpp_generator.h"
#include "flatbuffers/util.h"
#include <sstream>
#include "flatbuffers/util.h"
namespace grpc_cpp_generator {
namespace {
grpc::string message_header_ext() { return "_generated.h"; }
grpc::string service_header_ext() { return ".grpc.fb.h"; }
template <class T>
grpc::string as_string(T x) {
template<class T> grpc::string as_string(T x) {
std::ostringstream out;
out << x;
return out.str();
@@ -76,10 +42,7 @@ grpc::string FilenameIdentifier(const grpc::string &filename) {
}
} // namespace
template <class T, size_t N>
T *array_end(T (&array)[N]) {
return array + N;
}
template<class T, size_t N> T *array_end(T (&array)[N]) { return array + N; }
void PrintIncludes(grpc_generator::Printer *printer,
const std::vector<grpc::string> &headers,
@@ -92,9 +55,7 @@ void PrintIncludes(grpc_generator::Printer *printer,
auto &s = params.grpc_search_path;
if (!s.empty()) {
vars["l"] += s;
if (s[s.size() - 1] != '/') {
vars["l"] += '/';
}
if (s[s.size() - 1] != '/') { vars["l"] += '/'; }
}
for (auto i = headers.begin(); i != headers.end(); i++) {
@@ -144,15 +105,16 @@ grpc::string GetHeaderIncludes(grpc_generator::File *file,
std::map<grpc::string, grpc::string> vars;
static const char *headers_strs[] = {
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h",
"grpcpp/impl/codegen/method_handler.h",
"grpcpp/impl/codegen/proto_utils.h",
"grpcpp/impl/codegen/rpc_method.h",
"grpcpp/impl/codegen/service_type.h",
"grpcpp/impl/codegen/status.h",
"grpcpp/impl/codegen/stub_options.h",
"grpcpp/impl/codegen/sync_stream.h"};
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h",
"grpcpp/impl/codegen/method_handler.h",
"grpcpp/impl/codegen/proto_utils.h",
"grpcpp/impl/codegen/rpc_method.h",
"grpcpp/impl/codegen/service_type.h",
"grpcpp/impl/codegen/status.h",
"grpcpp/impl/codegen/stub_options.h",
"grpcpp/impl/codegen/sync_stream.h"
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params);
printer->Print(vars, "\n");
@@ -187,8 +149,8 @@ void PrintHeaderClientMethodInterfaces(
grpc::string prefix;
grpc::string method_params; // extra arguments to method
grpc::string raw_args; // extra arguments to raw version of method
} async_prefixes[] = {{"Async", ", void* tag", ", tag"},
{"PrepareAsync", "", ""}};
} async_prefixes[] = { { "Async", ", void* tag", ", tag" },
{ "PrepareAsync", "", "" } };
if (is_public) {
if (method->NoStreaming()) {
@@ -196,8 +158,9 @@ void PrintHeaderClientMethodInterfaces(
*vars,
"virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
"const $Request$& request, $Response$* response) = 0;\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print(
*vars,
@@ -228,8 +191,9 @@ void PrintHeaderClientMethodInterfaces(
"($Method$Raw(context, response));\n");
printer->Outdent();
printer->Print("}\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -262,8 +226,9 @@ void PrintHeaderClientMethodInterfaces(
"($Method$Raw(context, request));\n");
printer->Outdent();
printer->Print("}\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -295,8 +260,9 @@ void PrintHeaderClientMethodInterfaces(
"$Method$Raw(context));\n");
printer->Outdent();
printer->Print("}\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -318,8 +284,9 @@ void PrintHeaderClientMethodInterfaces(
}
} else {
if (method->NoStreaming()) {
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print(
*vars,
@@ -334,8 +301,9 @@ void PrintHeaderClientMethodInterfaces(
"virtual ::grpc::ClientWriterInterface< $Request$>*"
" $Method$Raw("
"::grpc::ClientContext* context, $Response$* response) = 0;\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
printer->Print(
@@ -351,8 +319,9 @@ void PrintHeaderClientMethodInterfaces(
"virtual ::grpc::ClientReaderInterface< $Response$>* "
"$Method$Raw("
"::grpc::ClientContext* context, const $Request$& request) = 0;\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
printer->Print(
@@ -367,8 +336,9 @@ void PrintHeaderClientMethodInterfaces(
"virtual ::grpc::ClientReaderWriterInterface< $Request$, "
"$Response$>* "
"$Method$Raw(::grpc::ClientContext* context) = 0;\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
printer->Print(
@@ -393,8 +363,8 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
grpc::string prefix;
grpc::string method_params; // extra arguments to method
grpc::string raw_args; // extra arguments to raw version of method
} async_prefixes[] = {{"Async", ", void* tag", ", tag"},
{"PrepareAsync", "", ""}};
} async_prefixes[] = { { "Async", ", void* tag", ", tag" },
{ "PrepareAsync", "", "" } };
if (is_public) {
if (method->NoStreaming()) {
@@ -402,8 +372,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
*vars,
"::grpc::Status $Method$(::grpc::ClientContext* context, "
"const $Request$& request, $Response$* response) override;\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print(
*vars,
@@ -431,8 +402,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
"($Method$Raw(context, response));\n");
printer->Outdent();
printer->Print("}\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -463,8 +435,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
"($Method$Raw(context, request));\n");
printer->Outdent();
printer->Print("}\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -494,8 +467,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
"$Method$Raw(context));\n");
printer->Outdent();
printer->Print("}\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -516,8 +490,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
}
} else {
if (method->NoStreaming()) {
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print(
*vars,
@@ -531,8 +506,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
"::grpc::ClientWriter< $Request$>* $Method$Raw("
"::grpc::ClientContext* context, $Response$* response) "
"override;\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -547,8 +523,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
"::grpc::ClientReader< $Response$>* $Method$Raw("
"::grpc::ClientContext* context, const $Request$& request)"
" override;\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -562,8 +539,9 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
printer->Print(*vars,
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
"$Method$Raw(::grpc::ClientContext* context) override;\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
@@ -630,7 +608,8 @@ void PrintHeaderServerMethodAsync(grpc_generator::Printer *printer,
"class WithAsyncMethod_$Method$ : public BaseClass {\n");
printer->Print(
" private:\n"
" void BaseClassMustBeDerivedFromService(const Service */*service*/) {}\n");
" void BaseClassMustBeDerivedFromService(const Service */*service*/) "
"{}\n");
printer->Print(" public:\n");
printer->Indent();
printer->Print(*vars,
@@ -849,7 +828,8 @@ void PrintHeaderServerMethodGeneric(
"class WithGenericMethod_$Method$ : public BaseClass {\n");
printer->Print(
" private:\n"
" void BaseClassMustBeDerivedFromService(const Service */*service*/) {}\n");
" void BaseClassMustBeDerivedFromService(const Service */*service*/) "
"{}\n");
printer->Print(" public:\n");
printer->Indent();
printer->Print(*vars,
@@ -1001,9 +981,7 @@ void PrintHeaderService(grpc_generator::Printer *printer,
printer->Print(*vars, "WithAsyncMethod_$method_name$<");
}
printer->Print("Service");
for (int i = 0; i < service->method_count(); ++i) {
printer->Print(" >");
}
for (int i = 0; i < service->method_count(); ++i) { printer->Print(" >"); }
printer->Print(" AsyncService;\n");
// Server side - Generic
@@ -1028,9 +1006,7 @@ void PrintHeaderService(grpc_generator::Printer *printer,
}
printer->Print("Service");
for (int i = 0; i < service->method_count(); ++i) {
if (service->method(i)->NoStreaming()) {
printer->Print(" >");
}
if (service->method(i)->NoStreaming()) { printer->Print(" >"); }
}
printer->Print(" StreamedUnaryService;\n");
@@ -1052,9 +1028,7 @@ void PrintHeaderService(grpc_generator::Printer *printer,
printer->Print("Service");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
if (ServerOnlyStreaming(method.get())) {
printer->Print(" >");
}
if (ServerOnlyStreaming(method.get())) { printer->Print(" >"); }
}
printer->Print(" SplitStreamedService;\n");
@@ -1095,9 +1069,7 @@ grpc::string GetHeaderServices(grpc_generator::File *file,
// Package string is empty or ends with a dot. It is used to fully qualify
// method names.
vars["Package"] = file->package();
if (!file->package().empty()) {
vars["Package"].append(".");
}
if (!file->package().empty()) { vars["Package"].append("."); }
if (!params.services_namespace.empty()) {
vars["services_namespace"] = params.services_namespace;
@@ -1155,6 +1127,7 @@ grpc::string GetSourcePrologue(grpc_generator::File *file,
vars["filename"] = file->filename();
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = file->message_header_ext();
vars["service_header_ext"] = file->service_header_ext();
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
@@ -1162,6 +1135,7 @@ grpc::string GetSourcePrologue(grpc_generator::File *file,
"// 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");
}
@@ -1177,14 +1151,15 @@ grpc::string GetSourceIncludes(grpc_generator::File *file,
std::map<grpc::string, grpc::string> vars;
static const char *headers_strs[] = {
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h",
"grpcpp/impl/codegen/channel_interface.h",
"grpcpp/impl/codegen/client_unary_call.h",
"grpcpp/impl/codegen/method_handler.h",
"grpcpp/impl/codegen/rpc_service_method.h",
"grpcpp/impl/codegen/service_type.h",
"grpcpp/impl/codegen/sync_stream.h"};
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h",
"grpcpp/impl/codegen/channel_interface.h",
"grpcpp/impl/codegen/client_unary_call.h",
"grpcpp/impl/codegen/method_handler.h",
"grpcpp/impl/codegen/rpc_service_method.h",
"grpcpp/impl/codegen/service_type.h",
"grpcpp/impl/codegen/sync_stream.h"
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params);
@@ -1213,8 +1188,8 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
grpc::string start; // bool literal expressed as string
grpc::string method_params; // extra arguments to method
grpc::string create_args; // extra arguments to creator
} async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
{"PrepareAsync", "false", "", ", nullptr"}};
} async_prefixes[] = { { "Async", "true", ", void* tag", ", tag" },
{ "PrepareAsync", "false", "", ", nullptr" } };
if (method->NoStreaming()) {
printer->Print(*vars,
"::grpc::Status $ns$$Service$::Stub::$Method$("
@@ -1224,8 +1199,9 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
" return ::grpc::internal::BlockingUnaryCall"
"(channel_.get(), rpcmethod_$Method$_, "
"context, request, response);\n}\n\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
printer->Print(*vars,
@@ -1255,8 +1231,9 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
"rpcmethod_$Method$_, "
"context, response);\n"
"}\n\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
@@ -1287,8 +1264,9 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
"rpcmethod_$Method$_, "
"context, request);\n"
"}\n\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
@@ -1319,8 +1297,9 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
"rpcmethod_$Method$_, "
"context);\n"
"}\n\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
@@ -1349,10 +1328,11 @@ void PrintSourceServerMethod(grpc_generator::Printer *printer,
(*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name();
if (method->NoStreaming()) {
printer->Print(*vars,
"::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* /*context*/, "
"const $Request$* /*request*/, $Response$* /*response*/) {\n");
printer->Print(
*vars,
"::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* /*context*/, "
"const $Request$* /*request*/, $Response$* /*response*/) {\n");
printer->Print(
" return ::grpc::Status("
"::grpc::StatusCode::UNIMPLEMENTED, \"\");\n");
@@ -1517,9 +1497,7 @@ grpc::string GetSourceServices(grpc_generator::File *file,
// Package string is empty or ends with a dot. It is used to fully qualify
// method names.
vars["Package"] = file->package();
if (!file->package().empty()) {
vars["Package"].append(".");
}
if (!file->package().empty()) { vars["Package"].append("."); }
if (!params.services_namespace.empty()) {
vars["ns"] = params.services_namespace + "::";
vars["prefix"] = params.services_namespace;
@@ -1591,9 +1569,9 @@ grpc::string GetMockIncludes(grpc_generator::File *file,
std::map<grpc::string, grpc::string> vars;
static const char *headers_strs[] = {
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/sync_stream.h",
"gmock/gmock.h",
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/sync_stream.h",
"gmock/gmock.h",
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params);
@@ -1623,15 +1601,17 @@ void PrintMockClientMethods(grpc_generator::Printer *printer,
grpc::string prefix;
grpc::string method_params; // extra arguments to method
int extra_method_param_count;
} async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
} async_prefixes[] = { { "Async", ", void* tag", 1 },
{ "PrepareAsync", "", 0 } };
if (method->NoStreaming()) {
printer->Print(
*vars,
"MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
"const $Request$& request, $Response$* response));\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
printer->Print(
*vars,
@@ -1646,12 +1626,13 @@ void PrintMockClientMethods(grpc_generator::Printer *printer,
"MOCK_METHOD2($Method$Raw, "
"::grpc::ClientWriterInterface< $Request$>*"
"(::grpc::ClientContext* context, $Response$* response));\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["MockArgs"] =
flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
printer->Print(*vars,
"MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
"::grpc::ClientAsyncWriterInterface< $Request$>*"
@@ -1664,8 +1645,9 @@ void PrintMockClientMethods(grpc_generator::Printer *printer,
"MOCK_METHOD2($Method$Raw, "
"::grpc::ClientReaderInterface< $Response$>*"
"(::grpc::ClientContext* context, const $Request$& request));\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["MockArgs"] =
@@ -1683,8 +1665,9 @@ void PrintMockClientMethods(grpc_generator::Printer *printer,
"MOCK_METHOD1($Method$Raw, "
"::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
"(::grpc::ClientContext* context));\n");
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
auto& async_prefix = async_prefixes[i];
for (size_t i = 0; i < sizeof(async_prefixes) / sizeof(async_prefixes[0]);
i++) {
auto &async_prefix = async_prefixes[i];
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
(*vars)["MockArgs"] =
@@ -1725,9 +1708,7 @@ grpc::string GetMockServices(grpc_generator::File *file,
// Package string is empty or ends with a dot. It is used to fully qualify
// method names.
vars["Package"] = file->package();
if (!file->package().empty()) {
vars["Package"].append(".");
}
if (!file->package().empty()) { vars["Package"].append("."); }
if (!params.services_namespace.empty()) {
vars["services_namespace"] = params.services_namespace;

View File

@@ -1,36 +1,3 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
@@ -41,12 +8,11 @@
#include <memory>
#include <vector>
#include "src/compiler/config.h"
#include "src/compiler/schema_interface.h"
#ifndef GRPC_CUSTOM_STRING
#include <string>
#define GRPC_CUSTOM_STRING std::string
# include <string>
# define GRPC_CUSTOM_STRING std::string
#endif
namespace grpc {

View File

@@ -1,47 +1,13 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation AN/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <map>
#include <cctype>
#include <sstream>
#include "src/compiler/go_generator.h"
template <class T>
grpc::string as_string(T x) {
std::ostringstream out;
out << x;
return out.str();
#include <cctype>
#include <map>
#include <sstream>
template<class T> grpc::string as_string(T x) {
std::ostringstream out;
out << x;
return out.str();
}
inline bool ClientOnlyStreaming(const grpc_generator::Method *method) {
@@ -56,18 +22,16 @@ namespace grpc_go_generator {
// Returns string with first letter to lowerCase
grpc::string unexportName(grpc::string s) {
if (s.empty())
return s;
s[0] = static_cast<char>(std::tolower(s[0]));
return s;
if (s.empty()) return s;
s[0] = static_cast<char>(std::tolower(s[0]));
return s;
}
// Returns string with first letter to uppercase
grpc::string exportName(grpc::string s) {
if (s.empty())
return s;
s[0] = static_cast<char>(std::toupper(s[0]));
return s;
if (s.empty()) return s;
s[0] = static_cast<char>(std::toupper(s[0]));
return s;
}
void GenerateError(grpc_generator::Printer *printer,
@@ -82,50 +46,65 @@ void GenerateError(grpc_generator::Printer *printer,
}
// Generates imports for the service
void GenerateImports(grpc_generator::File *file, grpc_generator::Printer *printer,
void GenerateImports(grpc_generator::File *file,
grpc_generator::Printer *printer,
std::map<grpc::string, grpc::string> vars) {
vars["filename"] = file->filename();
printer->Print("//Generated by gRPC Go plugin\n");
printer->Print("//If you make any local changes, they will be lost\n");
printer->Print(vars, "//source: $filename$\n\n");
printer->Print(vars, "package $Package$\n\n");
printer->Print("import (\n");
printer->Indent();
printer->Print(vars, "$context$ \"context\"\n");
vars["filename"] = file->filename();
printer->Print("//Generated by gRPC Go plugin\n");
printer->Print("//If you make any local changes, they will be lost\n");
printer->Print(vars, "//source: $filename$\n\n");
printer->Print(vars, "package $Package$\n\n");
printer->Print("import (\n");
printer->Indent();
printer->Print(vars, "$context$ \"context\"\n");
printer->Print("flatbuffers \"github.com/google/flatbuffers/go\"\n");
printer->Print(vars, "$grpc$ \"google.golang.org/grpc\"\n");
printer->Print(vars, "$grpc$ \"google.golang.org/grpc\"\n");
printer->Print("\"google.golang.org/grpc/codes\"\n");
printer->Print("\"google.golang.org/grpc/status\"\n");
printer->Outdent();
printer->Print(")\n\n");
printer->Outdent();
printer->Print(")\n\n");
}
// Generates Server method signature source
void GenerateServerMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
void GenerateServerMethodSignature(const grpc_generator::Method *method,
grpc_generator::Printer *printer,
std::map<grpc::string, grpc::string> vars) {
vars["Method"] = exportName(method->name());
vars["Request"] = method->get_input_type_name();
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
if (method->NoStreaming()) {
printer->Print(vars, "$Method$($context$.Context, *$Request$) (*$Response$, error)$Ending$");
} else if (ServerOnlyStreaming(method)) {
printer->Print(vars, "$Method$(*$Request$, $Service$_$Method$Server) error$Ending$");
} else {
printer->Print(vars, "$Method$($Service$_$Method$Server) error$Ending$");
}
vars["Request"] = method->get_input_type_name();
vars["Response"] = (vars["CustomMethodIO"] == "")
? method->get_output_type_name()
: vars["CustomMethodIO"];
if (method->NoStreaming()) {
printer->Print(
vars,
"$Method$($context$.Context, *$Request$) (*$Response$, error)$Ending$");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
vars, "$Method$(*$Request$, $Service$_$Method$Server) error$Ending$");
} else {
printer->Print(vars, "$Method$($Service$_$Method$Server) error$Ending$");
}
}
void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
void GenerateServerMethod(const grpc_generator::Method *method,
grpc_generator::Printer *printer,
std::map<grpc::string, grpc::string> vars) {
vars["Method"] = exportName(method->name());
vars["Request"] = method->get_input_type_name();
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
vars["FullMethodName"] = "/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
if (method->NoStreaming()) {
printer->Print(vars, "func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) (interface{}, error) {\n");
printer->Indent();
printer->Print(vars, "in := new($Request$)\n");
vars["Method"] = exportName(method->name());
vars["Request"] = method->get_input_type_name();
vars["Response"] = (vars["CustomMethodIO"] == "")
? method->get_output_type_name()
: vars["CustomMethodIO"];
vars["FullMethodName"] =
"/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
if (method->NoStreaming()) {
printer->Print(
vars,
"func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec "
"func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) "
"(interface{}, error) {\n");
printer->Indent();
printer->Print(vars, "in := new($Request$)\n");
vars["Error_Check"] = "err := dec(in); err != nil";
GenerateError(printer, vars);
printer->Print("if interceptor == nil {\n");
@@ -133,258 +112,281 @@ void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::
printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, in)\n");
printer->Outdent();
printer->Print("}\n");
printer->Print(vars, "info := &$grpc$.UnaryServerInfo{\n");
printer->Indent();
printer->Print("Server: srv,\n");
printer->Print(vars, "FullMethod: \"$FullMethodName$\",\n");
printer->Outdent();
printer->Print("}\n");
printer->Print(vars, "info := &$grpc$.UnaryServerInfo{\n");
printer->Indent();
printer->Print("Server: srv,\n");
printer->Print(vars, "FullMethod: \"$FullMethodName$\",\n");
printer->Outdent();
printer->Print("}\n");
printer->Outdent();
printer->Print("\n");
printer->Indent();
printer->Print(vars, "handler := func(ctx $context$.Context, req interface{}) (interface{}, error) {\n");
printer->Indent();
printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, req.(*$Request$))\n");
printer->Outdent();
printer->Print("}\n");
printer->Print("return interceptor(ctx, in, info, handler)\n");
printer->Outdent();
printer->Print("}\n");
return;
}
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Server";
printer->Print(vars, "func $Handler$(srv interface{}, stream $grpc$.ServerStream) error {\n");
printer->Indent();
if (ServerOnlyStreaming(method)) {
printer->Print(vars, "m := new($Request$)\n");
printer->Print(vars,
"handler := func(ctx $context$.Context, req interface{}) "
"(interface{}, error) {\n");
printer->Indent();
printer->Print(
vars, "return srv.($Service$Server).$Method$(ctx, req.(*$Request$))\n");
printer->Outdent();
printer->Print("}\n");
printer->Print("return interceptor(ctx, in, info, handler)\n");
printer->Outdent();
printer->Print("}\n");
return;
}
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Server";
printer->Print(
vars,
"func $Handler$(srv interface{}, stream $grpc$.ServerStream) error {\n");
printer->Indent();
if (ServerOnlyStreaming(method)) {
printer->Print(vars, "m := new($Request$)\n");
vars["Error_Check"] = "err := stream.RecvMsg(m); err != nil";
GenerateError(printer, vars, false);
printer->Print(vars, "return srv.($Service$Server).$Method$(m, &$StreamType${stream})\n");
} else {
printer->Print(vars, "return srv.($Service$Server).$Method$(&$StreamType${stream})\n");
}
printer->Outdent();
printer->Print("}\n\n");
printer->Print(
vars,
"return srv.($Service$Server).$Method$(m, &$StreamType${stream})\n");
} else {
printer->Print(
vars, "return srv.($Service$Server).$Method$(&$StreamType${stream})\n");
}
printer->Outdent();
printer->Print("}\n\n");
bool genSend = method->BidiStreaming() || ServerOnlyStreaming(method);
bool genRecv = method->BidiStreaming() || ClientOnlyStreaming(method);
bool genSendAndClose = ClientOnlyStreaming(method);
bool genSend = method->BidiStreaming() || ServerOnlyStreaming(method);
bool genRecv = method->BidiStreaming() || ClientOnlyStreaming(method);
bool genSendAndClose = ClientOnlyStreaming(method);
printer->Print(vars, "type $Service$_$Method$Server interface {\n");
printer->Indent();
if (genSend) {
printer->Print(vars, "Send(*$Response$) error\n");
}
if (genRecv) {
printer->Print(vars, "Recv() (*$Request$, error)\n");
}
if (genSendAndClose) {
printer->Print(vars, "SendAndClose(*$Response$) error\n");
}
printer->Print(vars, "$grpc$.ServerStream\n");
printer->Outdent();
printer->Print("}\n\n");
printer->Print(vars, "type $Service$_$Method$Server interface {\n");
printer->Indent();
if (genSend) { printer->Print(vars, "Send(*$Response$) error\n"); }
if (genRecv) { printer->Print(vars, "Recv() (*$Request$, error)\n"); }
if (genSendAndClose) {
printer->Print(vars, "SendAndClose(*$Response$) error\n");
}
printer->Print(vars, "$grpc$.ServerStream\n");
printer->Outdent();
printer->Print("}\n\n");
printer->Print(vars, "type $StreamType$ struct {\n");
printer->Indent();
printer->Print(vars, "$grpc$.ServerStream\n");
printer->Outdent();
printer->Print("}\n\n");
printer->Print(vars, "type $StreamType$ struct {\n");
printer->Indent();
printer->Print(vars, "$grpc$.ServerStream\n");
printer->Outdent();
printer->Print("}\n\n");
if (genSend) {
printer->Print(vars, "func (x *$StreamType$) Send(m *$Response$) error {\n");
printer->Indent();
printer->Print("return x.ServerStream.SendMsg(m)\n");
printer->Outdent();
printer->Print("}\n\n");
}
if (genRecv) {
printer->Print(vars, "func (x *$StreamType$) Recv() (*$Request$, error) {\n");
printer->Indent();
printer->Print(vars, "m := new($Request$)\n");
if (genSend) {
printer->Print(vars,
"func (x *$StreamType$) Send(m *$Response$) error {\n");
printer->Indent();
printer->Print("return x.ServerStream.SendMsg(m)\n");
printer->Outdent();
printer->Print("}\n\n");
}
if (genRecv) {
printer->Print(vars,
"func (x *$StreamType$) Recv() (*$Request$, error) {\n");
printer->Indent();
printer->Print(vars, "m := new($Request$)\n");
vars["Error_Check"] = "err := x.ServerStream.RecvMsg(m); err != nil";
GenerateError(printer, vars);
printer->Print("return m, nil\n");
printer->Outdent();
printer->Print("}\n\n");
}
if (genSendAndClose) {
printer->Print(vars, "func (x *$StreamType$) SendAndClose(m *$Response$) error {\n");
printer->Indent();
printer->Print("return x.ServerStream.SendMsg(m)\n");
printer->Outdent();
printer->Print("}\n\n");
}
printer->Print("return m, nil\n");
printer->Outdent();
printer->Print("}\n\n");
}
if (genSendAndClose) {
printer->Print(
vars, "func (x *$StreamType$) SendAndClose(m *$Response$) error {\n");
printer->Indent();
printer->Print("return x.ServerStream.SendMsg(m)\n");
printer->Outdent();
printer->Print("}\n\n");
}
}
// Generates Client method signature source
void GenerateClientMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
void GenerateClientMethodSignature(const grpc_generator::Method *method,
grpc_generator::Printer *printer,
std::map<grpc::string, grpc::string> vars) {
vars["Method"] = exportName(method->name());
vars["Request"] = ", in *" + ((vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"]);
if (ClientOnlyStreaming(method) || method->BidiStreaming()) {
vars["Request"] = "";
}
vars["Response"] = "*" + method->get_output_type_name();
if (ClientOnlyStreaming(method) || method->BidiStreaming() || ServerOnlyStreaming(method)) {
vars["Response"] = vars["Service"] + "_" + vars["Method"] + "Client" ;
}
printer->Print(vars, "$Method$(ctx $context$.Context$Request$,\n\topts ...$grpc$.CallOption) ($Response$, error)$Ending$");
vars["Method"] = exportName(method->name());
vars["Request"] =
", in *" + ((vars["CustomMethodIO"] == "") ? method->get_input_type_name()
: vars["CustomMethodIO"]);
if (ClientOnlyStreaming(method) || method->BidiStreaming()) {
vars["Request"] = "";
}
vars["Response"] = "*" + method->get_output_type_name();
if (ClientOnlyStreaming(method) || method->BidiStreaming() ||
ServerOnlyStreaming(method)) {
vars["Response"] = vars["Service"] + "_" + vars["Method"] + "Client";
}
printer->Print(vars,
"$Method$(ctx $context$.Context$Request$,\n\topts "
"...$grpc$.CallOption) ($Response$, error)$Ending$");
}
// Generates Client method source
void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
void GenerateClientMethod(const grpc_generator::Method *method,
grpc_generator::Printer *printer,
std::map<grpc::string, grpc::string> vars) {
printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
vars["Ending"] = " {\n";
GenerateClientMethodSignature(method, printer, vars);
printer->Indent();
vars["Method"] = exportName(method->name());
vars["Request"] = (vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"];
vars["Response"] = method->get_output_type_name();
vars["FullMethodName"] = "/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
if (method->NoStreaming()) {
printer->Print(vars, "out := new($Response$)\n");
printer->Print(vars, "err := c.cc.Invoke(ctx, \"$FullMethodName$\", in, out, opts...)\n");
GenerateClientMethodSignature(method, printer, vars);
printer->Indent();
vars["Method"] = exportName(method->name());
vars["Request"] = (vars["CustomMethodIO"] == "")
? method->get_input_type_name()
: vars["CustomMethodIO"];
vars["Response"] = method->get_output_type_name();
vars["FullMethodName"] =
"/" + vars["ServicePrefix"] + vars["Service"] + "/" + vars["Method"];
if (method->NoStreaming()) {
printer->Print(vars, "out := new($Response$)\n");
printer->Print(
vars,
"err := c.cc.Invoke(ctx, \"$FullMethodName$\", in, out, opts...)\n");
vars["Error_Check"] = "err != nil";
GenerateError(printer, vars);
printer->Print("return out, nil\n");
printer->Outdent();
printer->Print("}\n\n");
return;
}
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Client";
printer->Print(vars, "stream, err := c.cc.NewStream(ctx, &$MethodDesc$, \"$FullMethodName$\", opts...)\n");
printer->Print("return out, nil\n");
printer->Outdent();
printer->Print("}\n\n");
return;
}
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Client";
printer->Print(vars,
"stream, err := c.cc.NewStream(ctx, &$MethodDesc$, "
"\"$FullMethodName$\", opts...)\n");
vars["Error_Check"] = "err != nil";
GenerateError(printer, vars);
printer->Print(vars, "x := &$StreamType${stream}\n");
if (ServerOnlyStreaming(method)) {
printer->Print(vars, "x := &$StreamType${stream}\n");
if (ServerOnlyStreaming(method)) {
vars["Error_Check"] = "err := x.ClientStream.SendMsg(in); err != nil";
GenerateError(printer, vars);
vars["Error_Check"] = "err := x.ClientStream.CloseSend(); err != nil";
GenerateError(printer, vars);
}
printer->Print("return x, nil\n");
printer->Outdent();
printer->Print("}\n\n");
}
printer->Print("return x, nil\n");
printer->Outdent();
printer->Print("}\n\n");
bool genSend = method->BidiStreaming() || ClientOnlyStreaming(method);
bool genRecv = method->BidiStreaming() || ServerOnlyStreaming(method);
bool genCloseAndRecv = ClientOnlyStreaming(method);
bool genSend = method->BidiStreaming() || ClientOnlyStreaming(method);
bool genRecv = method->BidiStreaming() || ServerOnlyStreaming(method);
bool genCloseAndRecv = ClientOnlyStreaming(method);
//Stream interface
printer->Print(vars, "type $Service$_$Method$Client interface {\n");
printer->Indent();
if (genSend) {
printer->Print(vars, "Send(*$Request$) error\n");
}
if (genRecv) {
printer->Print(vars, "Recv() (*$Response$, error)\n");
}
if (genCloseAndRecv) {
printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n");
}
printer->Print(vars, "$grpc$.ClientStream\n");
printer->Outdent();
printer->Print("}\n\n");
// Stream interface
printer->Print(vars, "type $Service$_$Method$Client interface {\n");
printer->Indent();
if (genSend) { printer->Print(vars, "Send(*$Request$) error\n"); }
if (genRecv) { printer->Print(vars, "Recv() (*$Response$, error)\n"); }
if (genCloseAndRecv) {
printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n");
}
printer->Print(vars, "$grpc$.ClientStream\n");
printer->Outdent();
printer->Print("}\n\n");
//Stream Client
printer->Print(vars, "type $StreamType$ struct {\n");
printer->Indent();
printer->Print(vars, "$grpc$.ClientStream\n");
printer->Outdent();
printer->Print("}\n\n");
// Stream Client
printer->Print(vars, "type $StreamType$ struct {\n");
printer->Indent();
printer->Print(vars, "$grpc$.ClientStream\n");
printer->Outdent();
printer->Print("}\n\n");
if (genSend) {
printer->Print(vars, "func (x *$StreamType$) Send(m *$Request$) error {\n");
printer->Indent();
printer->Print("return x.ClientStream.SendMsg(m)\n");
printer->Outdent();
printer->Print("}\n\n");
}
if (genSend) {
printer->Print(vars, "func (x *$StreamType$) Send(m *$Request$) error {\n");
printer->Indent();
printer->Print("return x.ClientStream.SendMsg(m)\n");
printer->Outdent();
printer->Print("}\n\n");
}
if (genRecv) {
printer->Print(vars, "func (x *$StreamType$) Recv() (*$Response$, error) {\n");
printer->Indent();
printer->Print(vars, "m := new($Response$)\n");
if (genRecv) {
printer->Print(vars,
"func (x *$StreamType$) Recv() (*$Response$, error) {\n");
printer->Indent();
printer->Print(vars, "m := new($Response$)\n");
vars["Error_Check"] = "err := x.ClientStream.RecvMsg(m); err != nil";
GenerateError(printer, vars);
printer->Print("return m, nil\n");
printer->Outdent();
printer->Print("}\n\n");
}
printer->Print("return m, nil\n");
printer->Outdent();
printer->Print("}\n\n");
}
if (genCloseAndRecv) {
printer->Print(vars, "func (x *$StreamType$) CloseAndRecv() (*$Response$, error) {\n");
printer->Indent();
if (genCloseAndRecv) {
printer->Print(
vars, "func (x *$StreamType$) CloseAndRecv() (*$Response$, error) {\n");
printer->Indent();
vars["Error_Check"] = "err := x.ClientStream.CloseSend(); err != nil";
GenerateError(printer, vars);
printer->Print(vars, "m := new($Response$)\n");
printer->Print(vars, "m := new($Response$)\n");
vars["Error_Check"] = "err := x.ClientStream.RecvMsg(m); err != nil";
GenerateError(printer, vars);
printer->Print("return m, nil\n");
printer->Outdent();
printer->Print("}\n\n");
}
printer->Print("return m, nil\n");
printer->Outdent();
printer->Print("}\n\n");
}
}
// Generates client API for the service
void GenerateService(const grpc_generator::Service *service, grpc_generator::Printer* printer,
void GenerateService(const grpc_generator::Service *service,
grpc_generator::Printer *printer,
std::map<grpc::string, grpc::string> vars) {
vars["Service"] = exportName(service->name());
// Client Interface
printer->Print(vars, "// Client API for $Service$ service\n");
printer->Print(vars, "type $Service$Client interface {\n");
printer->Indent();
vars["Service"] = exportName(service->name());
// Client Interface
printer->Print(vars, "// Client API for $Service$ service\n");
printer->Print(vars, "type $Service$Client interface {\n");
printer->Indent();
vars["Ending"] = "\n";
for (int i = 0; i < service->method_count(); i++) {
GenerateClientMethodSignature(service->method(i).get(), printer, vars);
}
printer->Outdent();
printer->Print("}\n\n");
for (int i = 0; i < service->method_count(); i++) {
GenerateClientMethodSignature(service->method(i).get(), printer, vars);
}
printer->Outdent();
printer->Print("}\n\n");
// Client structure
vars["ServiceUnexported"] = unexportName(vars["Service"]);
printer->Print(vars, "type $ServiceUnexported$Client struct {\n");
printer->Indent();
printer->Print(vars, "cc $grpc$.ClientConnInterface\n");
printer->Outdent();
printer->Print("}\n\n");
// Client structure
vars["ServiceUnexported"] = unexportName(vars["Service"]);
printer->Print(vars, "type $ServiceUnexported$Client struct {\n");
printer->Indent();
printer->Print(vars, "cc $grpc$.ClientConnInterface\n");
printer->Outdent();
printer->Print("}\n\n");
// NewClient
printer->Print(vars, "func New$Service$Client(cc $grpc$.ClientConnInterface) $Service$Client {\n");
printer->Indent();
printer->Print(vars, "return &$ServiceUnexported$Client{cc}");
printer->Outdent();
printer->Print("\n}\n\n");
// NewClient
printer->Print(vars,
"func New$Service$Client(cc $grpc$.ClientConnInterface) "
"$Service$Client {\n");
printer->Indent();
printer->Print(vars, "return &$ServiceUnexported$Client{cc}");
printer->Outdent();
printer->Print("\n}\n\n");
int unary_methods = 0, streaming_methods = 0;
vars["ServiceDesc"] = "_" + vars["Service"] + "_serviceDesc";
for (int i = 0; i < service->method_count(); i++) {
auto method = service->method(i);
if (method->NoStreaming()) {
vars["MethodDesc"] = vars["ServiceDesc"] + ".Method[" + as_string(unary_methods) + "]";
unary_methods++;
} else {
vars["MethodDesc"] = vars["ServiceDesc"] + ".Streams[" + as_string(streaming_methods) + "]";
streaming_methods++;
}
GenerateClientMethod(method.get(), printer, vars);
}
int unary_methods = 0, streaming_methods = 0;
vars["ServiceDesc"] = "_" + vars["Service"] + "_serviceDesc";
for (int i = 0; i < service->method_count(); i++) {
auto method = service->method(i);
if (method->NoStreaming()) {
vars["MethodDesc"] =
vars["ServiceDesc"] + ".Method[" + as_string(unary_methods) + "]";
unary_methods++;
} else {
vars["MethodDesc"] = vars["ServiceDesc"] + ".Streams[" +
as_string(streaming_methods) + "]";
streaming_methods++;
}
GenerateClientMethod(method.get(), printer, vars);
}
//Server Interface
printer->Print(vars, "// Server API for $Service$ service\n");
printer->Print(vars, "type $Service$Server interface {\n");
printer->Indent();
// Server Interface
printer->Print(vars, "// Server API for $Service$ service\n");
printer->Print(vars, "type $Service$Server interface {\n");
printer->Indent();
vars["Ending"] = "\n";
for (int i = 0; i < service->method_count(); i++) {
GenerateServerMethodSignature(service->method(i).get(), printer, vars);
}
for (int i = 0; i < service->method_count(); i++) {
GenerateServerMethodSignature(service->method(i).get(), printer, vars);
}
printer->Print(vars, "mustEmbedUnimplemented$Service$Server()\n");
printer->Outdent();
printer->Print("}\n\n");
printer->Outdent();
printer->Print("}\n\n");
printer->Print(vars, "type Unimplemented$Service$Server struct {\n");
printer->Print("}\n\n");
@@ -397,13 +399,17 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
printer->Print(vars, "func (Unimplemented$Service$Server) ");
GenerateServerMethodSignature(method.get(), printer, vars);
printer->Indent();
printer->Print(vars, "return $Nil$status.Errorf(codes.Unimplemented, \"method $Method$ not implemented\")\n");
printer->Print(vars,
"return $Nil$status.Errorf(codes.Unimplemented, \"method "
"$Method$ not implemented\")\n");
printer->Outdent();
printer->Print("}\n");
printer->Print("\n");
}
printer->Print(vars, "func (Unimplemented$Service$Server) mustEmbedUnimplemented$Service$Server() {}");
printer->Print(vars,
"func (Unimplemented$Service$Server) "
"mustEmbedUnimplemented$Service$Server() {}");
printer->Print("\n\n");
printer->Print(vars, "type Unsafe$Service$Server interface {\n");
@@ -411,91 +417,89 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
printer->Print(vars, "mustEmbedUnimplemented$Service$Server()\n");
printer->Outdent();
printer->Print("}\n\n");
// Server registration.
printer->Print(vars, "func Register$Service$Server(s $grpc$.ServiceRegistrar, srv $Service$Server) {\n");
printer->Indent();
printer->Print(vars, "s.RegisterService(&$ServiceDesc$, srv)\n");
printer->Outdent();
printer->Print("}\n\n");
// Server registration.
printer->Print(vars,
"func Register$Service$Server(s $grpc$.ServiceRegistrar, srv "
"$Service$Server) {\n");
printer->Indent();
printer->Print(vars, "s.RegisterService(&$ServiceDesc$, srv)\n");
printer->Outdent();
printer->Print("}\n\n");
for (int i = 0; i < service->method_count(); i++) {
GenerateServerMethod(service->method(i).get(), printer, vars);
}
//Service Descriptor
printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
printer->Indent();
printer->Print(vars, "ServiceName: \"$ServicePrefix$$Service$\",\n");
printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
printer->Indent();
for (int i = 0; i < service->method_count(); i++) {
auto method = service->method(i);
vars["Method"] = exportName(method->name());
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
if (method->NoStreaming()) {
printer->Print("{\n");
printer->Indent();
printer->Print(vars, "MethodName: \"$Method$\",\n");
printer->Print(vars, "Handler: $Handler$,\n");
printer->Outdent();
printer->Print("},\n");
}
}
printer->Outdent();
printer->Print("},\n");
printer->Print(vars, "Streams: []$grpc$.StreamDesc{\n");
printer->Indent();
for (int i = 0; i < service->method_count(); i++) {
auto method = service->method(i);
vars["Method"] = exportName(method->name());
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
if (!method->NoStreaming()) {
printer->Print("{\n");
printer->Indent();
printer->Print(vars, "StreamName: \"$Method$\",\n");
printer->Print(vars, "Handler: $Handler$,\n");
if (ClientOnlyStreaming(method.get())) {
printer->Print("ClientStreams: true,\n");
} else if (ServerOnlyStreaming(method.get())) {
printer->Print("ServerStreams: true,\n");
} else {
printer->Print("ServerStreams: true,\n");
printer->Print("ClientStreams: true,\n");
}
printer->Outdent();
printer->Print("},\n");
}
}
printer->Outdent();
printer->Print("},\n");
printer->Outdent();
printer->Print("}\n");
for (int i = 0; i < service->method_count(); i++) {
GenerateServerMethod(service->method(i).get(), printer, vars);
}
// Service Descriptor
printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
printer->Indent();
printer->Print(vars, "ServiceName: \"$ServicePrefix$$Service$\",\n");
printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
printer->Indent();
for (int i = 0; i < service->method_count(); i++) {
auto method = service->method(i);
vars["Method"] = exportName(method->name());
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
if (method->NoStreaming()) {
printer->Print("{\n");
printer->Indent();
printer->Print(vars, "MethodName: \"$Method$\",\n");
printer->Print(vars, "Handler: $Handler$,\n");
printer->Outdent();
printer->Print("},\n");
}
}
printer->Outdent();
printer->Print("},\n");
printer->Print(vars, "Streams: []$grpc$.StreamDesc{\n");
printer->Indent();
for (int i = 0; i < service->method_count(); i++) {
auto method = service->method(i);
vars["Method"] = exportName(method->name());
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
if (!method->NoStreaming()) {
printer->Print("{\n");
printer->Indent();
printer->Print(vars, "StreamName: \"$Method$\",\n");
printer->Print(vars, "Handler: $Handler$,\n");
if (ClientOnlyStreaming(method.get())) {
printer->Print("ClientStreams: true,\n");
} else if (ServerOnlyStreaming(method.get())) {
printer->Print("ServerStreams: true,\n");
} else {
printer->Print("ServerStreams: true,\n");
printer->Print("ClientStreams: true,\n");
}
printer->Outdent();
printer->Print("},\n");
}
}
printer->Outdent();
printer->Print("},\n");
printer->Outdent();
printer->Print("}\n");
}
// Returns source for the service
grpc::string GenerateServiceSource(grpc_generator::File *file,
const grpc_generator::Service *service,
grpc_go_generator::Parameters *parameters) {
grpc::string out;
auto p = file->CreatePrinter(&out, '\t');
grpc::string out;
auto p = file->CreatePrinter(&out, '\t');
p->SetIndentationSize(1);
auto printer = p.get();
std::map<grpc::string, grpc::string> vars;
vars["Package"] = parameters->package_name;
vars["ServicePrefix"] = parameters->service_prefix;
if (!parameters->service_prefix.empty())
vars["ServicePrefix"].append(".");
vars["grpc"] = "grpc";
vars["context"] = "context";
GenerateImports(file, printer, vars);
if (parameters->custom_method_io_type != "") {
vars["CustomMethodIO"] = parameters->custom_method_io_type;
}
GenerateService(service, printer, vars);
return out;
auto printer = p.get();
std::map<grpc::string, grpc::string> vars;
vars["Package"] = parameters->package_name;
vars["ServicePrefix"] = parameters->service_prefix;
if (!parameters->service_prefix.empty()) vars["ServicePrefix"].append(".");
vars["grpc"] = "grpc";
vars["context"] = "context";
GenerateImports(file, printer, vars);
if (parameters->custom_method_io_type != "") {
vars["CustomMethodIO"] = parameters->custom_method_io_type;
}
GenerateService(service, printer, vars);
return out;
}
}// Namespace grpc_go_generator
} // Namespace grpc_go_generator

View File

@@ -1,40 +1,8 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
//go generator is used to generate GRPC code for serialization system, such as flatbuffers
// go generator is used to generate GRPC code for serialization system, such as
// flatbuffers
#include <memory>
#include <vector>
@@ -43,14 +11,15 @@
namespace grpc_go_generator {
struct Parameters {
//Defines the custom parameter types for methods
//eg: flatbuffers uses flatbuffers.Builder as input for the client and output for the server
// Defines the custom parameter types for methods
// eg: flatbuffers uses flatbuffers.Builder as input for the client and output
// for the server
grpc::string custom_method_io_type;
//Package name for the service
// Package name for the service
grpc::string package_name;
//Prefix for RPC Calls
// Prefix for RPC Calls
grpc::string service_prefix;
};
@@ -59,6 +28,6 @@ grpc::string GenerateServiceSource(grpc_generator::File *file,
const grpc_generator::Service *service,
grpc_go_generator::Parameters *parameters);
}
} // namespace grpc_go_generator
#endif // GRPC_INTERNAL_COMPILER_GO_GENERATOR_H

View File

@@ -23,21 +23,18 @@
#include <utility>
#include <vector>
// just to get flatbuffer_version_string()
#include <flatbuffers/flatbuffers.h>
#include <flatbuffers/util.h>
#include "flatbuffers/util.h"
#define to_string flatbuffers::NumToString
// Stringify helpers used solely to cast GRPC_VERSION
#ifndef STR
#define STR(s) #s
# define STR(s) # s
#endif
#ifndef XSTR
#define XSTR(s) STR(s)
# define XSTR(s) STR(s)
#endif
typedef grpc_generator::Printer Printer;
typedef std::map<grpc::string, grpc::string> VARS;
typedef grpc_generator::Service ServiceDescriptor;
@@ -48,12 +45,11 @@ typedef grpc_generator::Method MethodDescriptor;
namespace grpc_java_generator {
typedef std::string string;
// Generates imports for the service
void GenerateImports(grpc_generator::File* file,
grpc_generator::Printer* printer, VARS& vars) {
void GenerateImports(grpc_generator::File *file,
grpc_generator::Printer *printer, VARS &vars) {
vars["filename"] = file->filename();
printer->Print(
vars,
"//Generated by flatc compiler (version $flatc_version$)\n");
printer->Print(vars,
"//Generated by flatc compiler (version $flatc_version$)\n");
printer->Print("//If you make any local changes, they will be lost\n");
printer->Print(vars, "//source: $filename$.fbs\n\n");
printer->Print(vars, "package $Package$;\n\n");
@@ -67,7 +63,7 @@ void GenerateImports(grpc_generator::File* file,
// Adjust a method name prefix identifier to follow the JavaBean spec:
// - decapitalize the first letter
// - remove embedded underscores & capitalize the following letter
static string MixedLower(const string& word) {
static string MixedLower(const string &word) {
string w;
w += static_cast<string::value_type>(tolower(word[0]));
bool after_underscore = false;
@@ -87,7 +83,7 @@ static string MixedLower(const string& word) {
// - An underscore is inserted where a lower case letter is followed by an
// upper case letter.
// - All letters are converted to upper case
static string ToAllUpperCase(const string& word) {
static string ToAllUpperCase(const string &word) {
string w;
for (size_t i = 0; i < word.length(); ++i) {
w += static_cast<string::value_type>(toupper(word[i]));
@@ -98,47 +94,47 @@ static string ToAllUpperCase(const string& word) {
return w;
}
static inline string LowerMethodName(const MethodDescriptor* method) {
static inline string LowerMethodName(const MethodDescriptor *method) {
return MixedLower(method->name());
}
static inline string MethodPropertiesFieldName(const MethodDescriptor* method) {
static inline string MethodPropertiesFieldName(const MethodDescriptor *method) {
return "METHOD_" + ToAllUpperCase(method->name());
}
static inline string MethodPropertiesGetterName(
const MethodDescriptor* method) {
const MethodDescriptor *method) {
return MixedLower("get_" + method->name() + "_method");
}
static inline string MethodIdFieldName(const MethodDescriptor* method) {
static inline string MethodIdFieldName(const MethodDescriptor *method) {
return "METHODID_" + ToAllUpperCase(method->name());
}
static inline string JavaClassName(VARS& vars, const string& name) {
static inline string JavaClassName(VARS &vars, const string &name) {
// string name = google::protobuf::compiler::java::ClassName(desc);
return vars["Package"] + name;
}
static inline string ServiceClassName(const string& service_name) {
static inline string ServiceClassName(const string &service_name) {
return service_name + "Grpc";
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in
// distribution.
template <typename ITR>
static void GrpcSplitStringToIteratorUsing(const string& full,
const char* delim, ITR& result) {
template<typename ITR>
static void GrpcSplitStringToIteratorUsing(const string &full,
const char *delim, ITR &result) {
// Optimize the common case where delim is a single character.
if (delim[0] != '\0' && delim[1] == '\0') {
char c = delim[0];
const char* p = full.data();
const char* end = p + full.size();
const char *p = full.data();
const char *end = p + full.size();
while (p != end) {
if (*p == c) {
++p;
} else {
const char* start = p;
const char *start = p;
while (++p != end && *p != c)
;
*result++ = string(start, p - start);
@@ -160,13 +156,13 @@ static void GrpcSplitStringToIteratorUsing(const string& full,
}
}
static void GrpcSplitStringUsing(const string& full, const char* delim,
std::vector<string>* result) {
static void GrpcSplitStringUsing(const string &full, const char *delim,
std::vector<string> *result) {
std::back_insert_iterator<std::vector<string>> it(*result);
GrpcSplitStringToIteratorUsing(full, delim, it);
}
static std::vector<string> GrpcSplit(const string& full, const char* delim) {
static std::vector<string> GrpcSplit(const string &full, const char *delim) {
std::vector<string> result;
GrpcSplitStringUsing(full, delim, &result);
return result;
@@ -174,7 +170,7 @@ static std::vector<string> GrpcSplit(const string& full, const char* delim) {
// TODO(nmittler): Remove once protobuf includes javadoc methods in
// distribution.
static string GrpcEscapeJavadoc(const string& input) {
static string GrpcEscapeJavadoc(const string &input) {
string result;
result.reserve(input.size() * 2);
@@ -221,9 +217,7 @@ static string GrpcEscapeJavadoc(const string& input) {
// Java interprets Unicode escape sequences anywhere!
result.append("&#92;");
break;
default:
result.push_back(c);
break;
default: result.push_back(c); break;
}
prev = c;
@@ -232,7 +226,7 @@ static string GrpcEscapeJavadoc(const string& input) {
return result;
}
static std::vector<string> GrpcGetDocLines(const string& comments) {
static std::vector<string> GrpcGetDocLines(const string &comments) {
if (!comments.empty()) {
// TODO(kenton): Ideally we should parse the comment text as Markdown and
// write it back as HTML, but this requires a Markdown parser. For now
@@ -243,27 +237,23 @@ static std::vector<string> GrpcGetDocLines(const string& comments) {
string escapedComments = GrpcEscapeJavadoc(comments);
std::vector<string> lines = GrpcSplit(escapedComments, "\n");
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
}
while (!lines.empty() && lines.back().empty()) { lines.pop_back(); }
return lines;
}
return std::vector<string>();
}
static std::vector<string> GrpcGetDocLinesForDescriptor(
const DescriptorType* descriptor) {
const DescriptorType *descriptor) {
return descriptor->GetAllComments();
// return GrpcGetDocLines(descriptor->GetLeadingComments("///"));
}
static void GrpcWriteDocCommentBody(Printer* printer, VARS& vars,
const std::vector<string>& lines,
static void GrpcWriteDocCommentBody(Printer *printer, VARS &vars,
const std::vector<string> &lines,
bool surroundWithPreTag) {
if (!lines.empty()) {
if (surroundWithPreTag) {
printer->Print(" * <pre>\n");
}
if (surroundWithPreTag) { printer->Print(" * <pre>\n"); }
for (size_t i = 0; i < lines.size(); i++) {
// Most lines should start with a space. Watch out for lines that start
@@ -277,73 +267,72 @@ static void GrpcWriteDocCommentBody(Printer* printer, VARS& vars,
}
}
if (surroundWithPreTag) {
printer->Print(" * </pre>\n");
}
if (surroundWithPreTag) { printer->Print(" * </pre>\n"); }
}
}
static void GrpcWriteDocComment(Printer* printer, VARS& vars,
const string& comments) {
static void GrpcWriteDocComment(Printer *printer, VARS &vars,
const string &comments) {
printer->Print("/**\n");
std::vector<string> lines = GrpcGetDocLines(comments);
GrpcWriteDocCommentBody(printer, vars, lines, false);
printer->Print(" */\n");
}
static void GrpcWriteServiceDocComment(Printer* printer, VARS& vars,
const ServiceDescriptor* service) {
static void GrpcWriteServiceDocComment(Printer *printer, VARS &vars,
const ServiceDescriptor *service) {
printer->Print("/**\n");
std::vector<string> lines = GrpcGetDocLinesForDescriptor(service);
GrpcWriteDocCommentBody(printer, vars, lines, true);
printer->Print(" */\n");
}
void GrpcWriteMethodDocComment(Printer* printer, VARS& vars,
const MethodDescriptor* method) {
void GrpcWriteMethodDocComment(Printer *printer, VARS &vars,
const MethodDescriptor *method) {
printer->Print("/**\n");
std::vector<string> lines = GrpcGetDocLinesForDescriptor(method);
GrpcWriteDocCommentBody(printer, vars, lines, true);
printer->Print(" */\n");
}
//outputs static singleton extractor for type stored in "extr_type" and "extr_type_name" vars
static void PrintTypeExtractor(Printer* p, VARS& vars) {
p->Print(
vars,
"private static volatile FlatbuffersUtils.FBExtactor<$extr_type$> "
"extractorOf$extr_type_name$;\n"
"private static FlatbuffersUtils.FBExtactor<$extr_type$> "
"getExtractorOf$extr_type_name$() {\n"
" if (extractorOf$extr_type_name$ != null) return "
"extractorOf$extr_type_name$;\n"
" synchronized ($service_class_name$.class) {\n"
" if (extractorOf$extr_type_name$ != null) return "
"extractorOf$extr_type_name$;\n"
" extractorOf$extr_type_name$ = new "
"FlatbuffersUtils.FBExtactor<$extr_type$>() {\n"
" public $extr_type$ extract (ByteBuffer buffer) {\n"
" return "
"$extr_type$.getRootAs$extr_type_name$(buffer);\n"
" }\n"
" };\n"
" return extractorOf$extr_type_name$;\n"
" }\n"
"}\n\n");
// outputs static singleton extractor for type stored in "extr_type" and
// "extr_type_name" vars
static void PrintTypeExtractor(Printer *p, VARS &vars) {
p->Print(vars,
"private static volatile FlatbuffersUtils.FBExtactor<$extr_type$> "
"extractorOf$extr_type_name$;\n"
"private static FlatbuffersUtils.FBExtactor<$extr_type$> "
"getExtractorOf$extr_type_name$() {\n"
" if (extractorOf$extr_type_name$ != null) return "
"extractorOf$extr_type_name$;\n"
" synchronized ($service_class_name$.class) {\n"
" if (extractorOf$extr_type_name$ != null) return "
"extractorOf$extr_type_name$;\n"
" extractorOf$extr_type_name$ = new "
"FlatbuffersUtils.FBExtactor<$extr_type$>() {\n"
" public $extr_type$ extract (ByteBuffer buffer) {\n"
" return "
"$extr_type$.getRootAs$extr_type_name$(buffer);\n"
" }\n"
" };\n"
" return extractorOf$extr_type_name$;\n"
" }\n"
"}\n\n");
}
static void PrintMethodFields(Printer* p, VARS& vars,
const ServiceDescriptor* service) {
static void PrintMethodFields(Printer *p, VARS &vars,
const ServiceDescriptor *service) {
p->Print("// Static method descriptors that strictly reflect the proto.\n");
vars["service_name"] = service->name();
//set of names of rpc input- and output- types that were already encountered.
//this is needed to avoid duplicating type extractor since it's possible that
//the same type is used as an input or output type of more than a single RPC method
// set of names of rpc input- and output- types that were already encountered.
// this is needed to avoid duplicating type extractor since it's possible that
// the same type is used as an input or output type of more than a single RPC
// method
std::set<std::string> encounteredTypes;
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
vars["arg_in_id"] = to_string(2L * i); //trying to make msvc 10 happy
vars["arg_in_id"] = to_string(2L * i); // trying to make msvc 10 happy
vars["arg_out_id"] = to_string(2L * i + 1);
vars["method_name"] = method->name();
vars["input_type_name"] = method->get_input_type_name();
@@ -353,8 +342,10 @@ static void PrintMethodFields(Printer* p, VARS& vars,
vars["method_field_name"] = MethodPropertiesFieldName(method.get());
vars["method_new_field_name"] = MethodPropertiesGetterName(method.get());
vars["method_method_name"] = MethodPropertiesGetterName(method.get());
bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
bool client_streaming =
method->ClientStreaming() || method->BidiStreaming();
bool server_streaming =
method->ServerStreaming() || method->BidiStreaming();
if (client_streaming) {
if (server_streaming) {
vars["method_type"] = "BIDI_STREAMING";
@@ -394,32 +385,32 @@ static void PrintMethodFields(Printer* p, VARS& vars,
}
p->Print(
vars,
"@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/"
"1901\")\n"
"public static $MethodDescriptor$<$input_type$,\n"
" $output_type$> $method_method_name$() {\n"
" $MethodDescriptor$<$input_type$, $output_type$> "
"$method_new_field_name$;\n"
" if (($method_new_field_name$ = "
"$service_class_name$.$method_new_field_name$) == null) {\n"
" synchronized ($service_class_name$.class) {\n"
" if (($method_new_field_name$ = "
"$service_class_name$.$method_new_field_name$) == null) {\n"
" $service_class_name$.$method_new_field_name$ = "
"$method_new_field_name$ = \n"
" $MethodDescriptor$.<$input_type$, "
"$output_type$>newBuilder()\n"
" .setType($MethodType$.$method_type$)\n"
" .setFullMethodName(generateFullMethodName(\n"
" \"$Package$$service_name$\", \"$method_name$\"))\n"
" .setSampledToLocalTracing(true)\n"
" .setRequestMarshaller(FlatbuffersUtils.marshaller(\n"
" $input_type$.class, "
"getExtractorOf$input_type_name$()))\n"
" .setResponseMarshaller(FlatbuffersUtils.marshaller(\n"
" $output_type$.class, "
"getExtractorOf$output_type_name$()))\n");
vars,
"@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/"
"1901\")\n"
"public static $MethodDescriptor$<$input_type$,\n"
" $output_type$> $method_method_name$() {\n"
" $MethodDescriptor$<$input_type$, $output_type$> "
"$method_new_field_name$;\n"
" if (($method_new_field_name$ = "
"$service_class_name$.$method_new_field_name$) == null) {\n"
" synchronized ($service_class_name$.class) {\n"
" if (($method_new_field_name$ = "
"$service_class_name$.$method_new_field_name$) == null) {\n"
" $service_class_name$.$method_new_field_name$ = "
"$method_new_field_name$ = \n"
" $MethodDescriptor$.<$input_type$, "
"$output_type$>newBuilder()\n"
" .setType($MethodType$.$method_type$)\n"
" .setFullMethodName(generateFullMethodName(\n"
" \"$Package$$service_name$\", \"$method_name$\"))\n"
" .setSampledToLocalTracing(true)\n"
" .setRequestMarshaller(FlatbuffersUtils.marshaller(\n"
" $input_type$.class, "
"getExtractorOf$input_type_name$()))\n"
" .setResponseMarshaller(FlatbuffersUtils.marshaller(\n"
" $output_type$.class, "
"getExtractorOf$output_type_name$()))\n");
// vars["proto_method_descriptor_supplier"] = service->name() +
// "MethodDescriptorSupplier";
@@ -451,11 +442,11 @@ enum StubType {
enum CallType { ASYNC_CALL = 0, BLOCKING_CALL = 1, FUTURE_CALL = 2 };
static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
const ServiceDescriptor* service);
static void PrintBindServiceMethodBody(Printer *p, VARS &vars,
const ServiceDescriptor *service);
// Prints a client interface or implementation class, or a server interface.
static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
static void PrintStub(Printer *p, VARS &vars, const ServiceDescriptor *service,
StubType type) {
const string service_name = service->name();
vars["service_name"] = service_name;
@@ -476,7 +467,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
break;
case BLOCKING_CLIENT_INTERFACE:
interface = true;
FLATBUFFERS_FALLTHROUGH(); // fall thru
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BLOCKING_CLIENT_IMPL:
call_type = BLOCKING_CALL;
stub_name += "BlockingStub";
@@ -484,7 +475,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
break;
case FUTURE_CLIENT_INTERFACE:
interface = true;
FLATBUFFERS_FALLTHROUGH(); // fall thru
FLATBUFFERS_FALLTHROUGH(); // fall thru
case FUTURE_CLIENT_IMPL:
call_type = FUTURE_CALL;
stub_name += "FutureStub";
@@ -501,9 +492,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
vars["client_name"] = client_name;
// Class head
if (!interface) {
GrpcWriteServiceDocComment(p, vars, service);
}
if (!interface) { GrpcWriteServiceDocComment(p, vars, service); }
if (impl_base) {
p->Print(vars,
"public static abstract class $abstract_name$ implements "
@@ -546,8 +535,10 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
vars["lower_method_name"] = LowerMethodName(&*method);
vars["method_method_name"] = MethodPropertiesGetterName(&*method);
bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
bool client_streaming =
method->ClientStreaming() || method->BidiStreaming();
bool server_streaming =
method->ServerStreaming() || method->BidiStreaming();
if (call_type == BLOCKING_CALL && client_streaming) {
// Blocking client interface with client streaming is not available
@@ -563,9 +554,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
p->Print("\n");
// TODO(nmittler): Replace with WriteMethodDocComment once included by the
// protobuf distro.
if (!interface) {
GrpcWriteMethodDocComment(p, vars, &*method);
}
if (!interface) { GrpcWriteMethodDocComment(p, vars, &*method); }
p->Print("public ");
switch (call_type) {
case BLOCKING_CALL:
@@ -630,8 +619,7 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
"responseObserver);\n");
}
break;
default:
break;
default: break;
}
} else if (!interface) {
switch (call_type) {
@@ -706,15 +694,15 @@ static void PrintStub(Printer* p, VARS& vars, const ServiceDescriptor* service,
}
static bool CompareMethodClientStreaming(
const std::unique_ptr<const grpc_generator::Method>& method1,
const std::unique_ptr<const grpc_generator::Method>& method2) {
const std::unique_ptr<const grpc_generator::Method> &method1,
const std::unique_ptr<const grpc_generator::Method> &method2) {
return method1->ClientStreaming() < method2->ClientStreaming();
}
// Place all method invocations into a single class to reduce memory footprint
// on Android.
static void PrintMethodHandlerClass(Printer* p, VARS& vars,
const ServiceDescriptor* service) {
static void PrintMethodHandlerClass(Printer *p, VARS &vars,
const ServiceDescriptor *service) {
// Sort method ids based on ClientStreaming() so switch tables are compact.
std::vector<std::unique_ptr<const grpc_generator::Method>> sorted_methods(
service->method_count());
@@ -724,7 +712,7 @@ static void PrintMethodHandlerClass(Printer* p, VARS& vars,
stable_sort(sorted_methods.begin(), sorted_methods.end(),
CompareMethodClientStreaming);
for (size_t i = 0; i < sorted_methods.size(); i++) {
auto& method = sorted_methods[i];
auto &method = sorted_methods[i];
vars["method_id"] = to_string(i);
vars["method_id_name"] = MethodIdFieldName(&*method);
p->Print(vars,
@@ -757,9 +745,7 @@ static void PrintMethodHandlerClass(Printer* p, VARS& vars,
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
if (method->ClientStreaming() || method->BidiStreaming()) {
continue;
}
if (method->ClientStreaming() || method->BidiStreaming()) { continue; }
vars["method_id_name"] = MethodIdFieldName(&*method);
vars["lower_method_name"] = LowerMethodName(&*method);
vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
@@ -791,9 +777,7 @@ static void PrintMethodHandlerClass(Printer* p, VARS& vars,
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
if (!(method->ClientStreaming() || method->BidiStreaming())) {
continue;
}
if (!(method->ClientStreaming() || method->BidiStreaming())) { continue; }
vars["method_id_name"] = MethodIdFieldName(&*method);
vars["lower_method_name"] = LowerMethodName(&*method);
vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
@@ -818,8 +802,8 @@ static void PrintMethodHandlerClass(Printer* p, VARS& vars,
p->Print("}\n\n");
}
static void PrintGetServiceDescriptorMethod(Printer* p, VARS& vars,
const ServiceDescriptor* service) {
static void PrintGetServiceDescriptorMethod(Printer *p, VARS &vars,
const ServiceDescriptor *service) {
vars["service_name"] = service->name();
// vars["proto_base_descriptor_supplier"] = service->name() +
// "BaseDescriptorSupplier"; vars["proto_file_descriptor_supplier"] =
@@ -911,8 +895,8 @@ static void PrintGetServiceDescriptorMethod(Printer* p, VARS& vars,
p->Print("}\n");
}
static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
const ServiceDescriptor* service) {
static void PrintBindServiceMethodBody(Printer *p, VARS &vars,
const ServiceDescriptor *service) {
vars["service_name"] = service->name();
p->Indent();
p->Print(vars,
@@ -927,8 +911,10 @@ static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
vars["input_type"] = JavaClassName(vars, method->get_input_type_name());
vars["output_type"] = JavaClassName(vars, method->get_output_type_name());
vars["method_id_name"] = MethodIdFieldName(&*method);
bool client_streaming = method->ClientStreaming() || method->BidiStreaming();
bool server_streaming = method->ServerStreaming() || method->BidiStreaming();
bool client_streaming =
method->ClientStreaming() || method->BidiStreaming();
bool server_streaming =
method->ServerStreaming() || method->BidiStreaming();
if (client_streaming) {
if (server_streaming) {
vars["calls_method"] = "asyncBidiStreamingCall";
@@ -962,8 +948,8 @@ static void PrintBindServiceMethodBody(Printer* p, VARS& vars,
p->Outdent();
}
static void PrintService(Printer* p, VARS& vars,
const ServiceDescriptor* service,
static void PrintService(Printer *p, VARS &vars,
const ServiceDescriptor *service,
bool disable_version) {
vars["service_name"] = service->name();
vars["service_class_name"] = ServiceClassName(service->name());
@@ -1043,7 +1029,7 @@ static void PrintService(Printer* p, VARS& vars,
p->Print("}\n");
}
void PrintStaticImports(Printer* p) {
void PrintStaticImports(Printer *p) {
p->Print(
"import java.nio.ByteBuffer;\n"
"import static "
@@ -1076,8 +1062,8 @@ void PrintStaticImports(Printer* p) {
"io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n\n");
}
void GenerateService(const grpc_generator::Service* service,
grpc_generator::Printer* printer, VARS& vars,
void GenerateService(const grpc_generator::Service *service,
grpc_generator::Printer *printer, VARS &vars,
bool disable_version) {
// All non-generated classes must be referred by fully qualified names to
// avoid collision with generated classes.
@@ -1113,8 +1099,8 @@ void GenerateService(const grpc_generator::Service* service,
}
grpc::string GenerateServiceSource(
grpc_generator::File* file, const grpc_generator::Service* service,
grpc_java_generator::Parameters* parameters) {
grpc_generator::File *file, const grpc_generator::Service *service,
grpc_java_generator::Parameters *parameters) {
grpc::string out;
auto printer = file->CreatePrinter(&out);
VARS vars;

View File

@@ -21,7 +21,6 @@
#include <utility>
#include "src/compiler/config.h"
#include "src/compiler/schema_interface.h"
namespace grpc_python_generator {

View File

@@ -19,11 +19,10 @@
#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
#include <map>
#include <memory>
#include <vector>
#include "src/compiler/config.h"
#ifndef GRPC_CUSTOM_STRING
# include <string>
# define GRPC_CUSTOM_STRING std::string

View File

@@ -1,40 +1,22 @@
/*
* Copyright 2020 Google Inc. All rights reserved.
*
* Copyright 2020, Google Inc.
* All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <memory>
#include <vector>
#include "src/compiler/config.h"
#include "src/compiler/schema_interface.h"
#ifndef GRPC_CUSTOM_STRING

View File

@@ -1,41 +1,7 @@
/*
*
* Copyright 2020, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <memory>
#include <vector>
#include <set>
#include <vector>
#include "src/compiler/config.h"
#include "src/compiler/schema_interface.h"
#ifndef GRPC_CUSTOM_STRING
@@ -58,4 +24,3 @@ grpc::string GenerateInterface(grpc_generator::File *file,
const grpc_generator::Service *service,
const grpc::string &filename);
} // namespace grpc_ts_generator

View File

@@ -1,8 +1,8 @@
package testing
import (
"../../tests/MyGame/Example"
flatbuffers "github.com/google/flatbuffers/go"
"github.com/google/flatbuffers/tests/MyGame/Example"
"context"
"net"
@@ -12,7 +12,9 @@ import (
"google.golang.org/grpc/encoding"
)
type server struct{}
type server struct {
Example.UnimplementedMonsterStorageServer
}
// test used to send and receive in grpc methods
var test = "Flatbuffers"
@@ -65,8 +67,12 @@ func RetrieveClient(c Example.MonsterStorageClient, t *testing.T) {
if err != nil {
t.Fatalf("Retrieve client failed: %v", err)
}
if string(out.Name()) != test {
t.Errorf("RetrieveClient failed: expected=%s, got=%s\n", test, out.Name())
monster, err := out.Recv()
if err != nil {
t.Fatalf("Recv failed: %v", err)
}
if string(monster.Name()) != test {
t.Errorf("RetrieveClient failed: expected=%s, got=%s\n", test, monster.Name())
t.Fail()
}
}

View File

@@ -140,7 +140,7 @@
#define FLATBUFFERS_VERSION_MAJOR 2
#define FLATBUFFERS_VERSION_MINOR 0
#define FLATBUFFERS_VERSION_REVISION 5
#define FLATBUFFERS_VERSION_REVISION 6
#define FLATBUFFERS_STRING_EXPAND(X) #X
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
namespace flatbuffers {

View File

@@ -42,14 +42,15 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
return static_cast<voffset_t>((field_id + fixed_fields) * sizeof(voffset_t));
}
template<typename T, typename Alloc>
template<typename T, typename Alloc = std::allocator<T>>
const T *data(const std::vector<T, Alloc> &v) {
// Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior.
static uint8_t t;
return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
}
template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) {
template<typename T, typename Alloc = std::allocator<T>>
T *data(std::vector<T, Alloc> &v) {
// Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior.
static uint8_t t;
@@ -285,9 +286,7 @@ class FlatBufferBuilder {
FieldLoc fl = { off, field };
buf_.scratch_push_small(fl);
num_field_loc++;
if (field > max_voffset_) {
max_voffset_ = field;
}
if (field > max_voffset_) { max_voffset_ = field; }
}
// Like PushElement, but additionally tracks the field this represents.
@@ -642,6 +641,17 @@ class FlatBufferBuilder {
return Offset<Vector<T>>(EndVector(len));
}
/// @brief Serialize an array like object into a FlatBuffer `vector`.
/// @tparam T The data type of the array elements.
/// @tparam C The type of the array.
/// @param[in] array A reference to an array like object of type `T` to
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename T, class C> Offset<Vector<T>> CreateVector(const C &array) {
return CreateVector(array.data(), array.size());
}
template<typename T>
Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
StartVector(len, sizeof(Offset<T>));
@@ -655,7 +665,7 @@ class FlatBufferBuilder {
/// buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename T, typename Alloc>
template<typename T, typename Alloc = std::allocator<T>>
Offset<Vector<T>> CreateVector(const std::vector<T, Alloc> &v) {
return CreateVector(data(v), v.size());
}
@@ -712,7 +722,7 @@ class FlatBufferBuilder {
/// buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename Alloc>
template<typename Alloc = std::allocator<std::string>>
Offset<Vector<Offset<String>>> CreateVectorOfStrings(
const std::vector<std::string, Alloc> &v) {
return CreateVectorOfStrings(v.cbegin(), v.cend());
@@ -841,7 +851,7 @@ class FlatBufferBuilder {
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename T, typename Alloc>
template<typename T, typename Alloc = std::allocator<T>>
Offset<Vector<const T *>> CreateVectorOfStructs(
const std::vector<T, Alloc> &v) {
return CreateVectorOfStructs(data(v), v.size());
@@ -857,7 +867,7 @@ class FlatBufferBuilder {
/// to the FlatBuffer struct.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename T, typename S, typename Alloc>
template<typename T, typename S, typename Alloc = std::allocator<T>>
Offset<Vector<const T *>> CreateVectorOfNativeStructs(
const std::vector<S, Alloc> &v, T (*const pack_func)(const S &)) {
return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func);
@@ -871,7 +881,7 @@ class FlatBufferBuilder {
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename T, typename S, typename Alloc>
template<typename T, typename S, typename Alloc = std::allocator<S>>
Offset<Vector<const T *>> CreateVectorOfNativeStructs(
const std::vector<S, Alloc> &v) {
return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
@@ -892,7 +902,7 @@ class FlatBufferBuilder {
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename T, typename Alloc>
template<typename T, typename Alloc = std::allocator<T>>
Offset<Vector<const T *>> CreateVectorOfSortedStructs(
std::vector<T, Alloc> *v) {
return CreateVectorOfSortedStructs(data(*v), v->size());
@@ -906,7 +916,7 @@ class FlatBufferBuilder {
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename T, typename S, typename Alloc>
template<typename T, typename S, typename Alloc = std::allocator<T>>
Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(
std::vector<S, Alloc> *v) {
return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
@@ -922,7 +932,7 @@ class FlatBufferBuilder {
/// where the vector is stored.
template<typename T>
Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) {
std::sort(v, v + len, StructKeyComparator<T>());
std::stable_sort(v, v + len, StructKeyComparator<T>());
return CreateVectorOfStructs(v, len);
}
@@ -941,7 +951,7 @@ class FlatBufferBuilder {
extern T Pack(const S &);
auto structs = StartVectorOfStructs<T>(len);
for (size_t i = 0; i < len; i++) { structs[i] = Pack(v[i]); }
std::sort(structs, structs + len, StructKeyComparator<T>());
std::stable_sort(structs, structs + len, StructKeyComparator<T>());
return EndVectorOfStructs<T>(len);
}
@@ -973,7 +983,7 @@ class FlatBufferBuilder {
template<typename T>
Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v,
size_t len) {
std::sort(v, v + len, TableKeyComparator<T>(buf_));
std::stable_sort(v, v + len, TableKeyComparator<T>(buf_));
return CreateVector(v, len);
}
@@ -984,7 +994,7 @@ class FlatBufferBuilder {
/// offsets to store in the buffer in sorted order.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename T, typename Alloc>
template<typename T, typename Alloc = std::allocator<T>>
Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
std::vector<Offset<T>, Alloc> *v) {
return CreateVectorOfSortedTables(data(*v), v->size());
@@ -1074,7 +1084,7 @@ class FlatBufferBuilder {
void SwapBufAllocator(FlatBufferBuilder &other) {
buf_.swap_allocator(other.buf_);
}
/// @brief The length of a FlatBuffer file header.
static const size_t kFileIdentifierLength =
::flatbuffers::kFileIdentifierLength;

View File

@@ -226,27 +226,13 @@ struct TypeTable {
};
// String which identifies the current version of FlatBuffers.
// flatbuffer_version_string is used by Google developers to identify which
// applications uploaded to Google Play are using this library. This allows
// the development team at Google to determine the popularity of the library.
// How it works: Applications that are uploaded to the Google Play Store are
// scanned for this version string. We track which applications are using it
// to measure popularity. You are free to remove it (of course) but we would
// appreciate if you left it in.
inline const char *flatbuffers_version_string() {
return "FlatBuffers " FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
}
// Weak linkage is culled by VS & doesn't work on cygwin.
// clang-format off
#if !defined(_WIN32) && !defined(__CYGWIN__)
extern volatile __attribute__((weak)) const char *flatbuffer_version_string;
volatile __attribute__((weak)) const char *flatbuffer_version_string =
"FlatBuffers "
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
#endif // !defined(_WIN32) && !defined(__CYGWIN__)
#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
inline E operator | (E lhs, E rhs){\
return E(T(lhs) | T(rhs));\

View File

@@ -31,6 +31,13 @@ namespace flatbuffers {
extern void LogCompilerWarn(const std::string &warn);
extern void LogCompilerError(const std::string &err);
struct FlatCOption {
std::string short_opt;
std::string long_opt;
std::string parameter;
std::string description;
};
class FlatCompiler {
public:
// Output generator for the various programming languages and formats we
@@ -42,17 +49,18 @@ class FlatCompiler {
typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser,
const std::string &path,
const std::string &file_name);
typedef bool (*ParsingCompletedFn)(const flatbuffers::Parser &parser,
const std::string &output_path);
GenerateFn generate;
const char *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;
FlatCOption option;
MakeRuleFn make_rule;
BfbsGenerator *bfbs_generator;
ParsingCompletedFn parsing_completed;
};
typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn,
@@ -79,6 +87,7 @@ class FlatCompiler {
int Compile(int argc, const char **argv);
std::string GetShortUsageString(const char *program_name) const;
std::string GetUsageString(const char *program_name) const;
private:

View File

@@ -53,7 +53,7 @@ enum Type {
FBT_INT = 1,
FBT_UINT = 2,
FBT_FLOAT = 3,
// Types above stored inline, types below store an offset.
// Types above stored inline, types below (except FBT_BOOL) store an offset.
FBT_KEY = 4,
FBT_STRING = 5,
FBT_INDIRECT_INT = 6,
@@ -81,6 +81,8 @@ enum Type {
FBT_BOOL = 26,
FBT_VECTOR_BOOL =
36, // To Allow the same type of conversion of type to vector type
FBT_MAX_TYPE = 37
};
inline bool IsInline(Type t) { return t <= FBT_FLOAT || t == FBT_BOOL; }
@@ -369,10 +371,7 @@ void AppendToString(std::string &s, T &&v, bool keys_quoted) {
class Reference {
public:
Reference()
: data_(nullptr),
parent_width_(0),
byte_width_(BIT_WIDTH_8),
type_(FBT_NULL) {}
: data_(nullptr), parent_width_(0), byte_width_(0), type_(FBT_NULL) {}
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
Type type)
@@ -573,7 +572,23 @@ class Reference {
auto keys = m.Keys();
auto vals = m.Values();
for (size_t i = 0; i < keys.size(); i++) {
keys[i].ToString(true, keys_quoted, s);
bool kq = keys_quoted;
if (!kq) {
// FlexBuffers keys may contain arbitrary characters, only allow
// unquoted if it looks like an "identifier":
const char *p = keys[i].AsKey();
if (!flatbuffers::is_alpha(*p) && *p != '_') {
kq = true;
} else {
while (*++p) {
if (!flatbuffers::is_alnum(*p) && *p != '_') {
kq = true;
break;
}
}
}
}
keys[i].ToString(true, kq, s);
s += ": ";
vals[i].ToString(true, keys_quoted, s);
if (i < keys.size() - 1) s += ", ";
@@ -757,6 +772,8 @@ class Reference {
return false;
}
friend class Verifier;
const uint8_t *data_;
uint8_t parent_width_;
uint8_t byte_width_;
@@ -1558,9 +1575,9 @@ class Builder FLATBUFFERS_FINAL_CLASS {
}
}
}
// If you get this assert, your fixed types are not one of:
// If you get this assert, your typed types are not one of:
// Int / UInt / Float / Key.
FLATBUFFERS_ASSERT(!fixed || IsTypedVectorElementType(vector_type));
FLATBUFFERS_ASSERT(!typed || IsTypedVectorElementType(vector_type));
auto byte_width = Align(bit_width);
// Write vector. First the keys width/offset if available, and size.
if (keys) {
@@ -1615,9 +1632,10 @@ class Builder FLATBUFFERS_FINAL_CLASS {
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 *>(buf_->data() + a.first);
auto strb = reinterpret_cast<const char *>(buf_->data() + b.first);
return strncmp(stra, strb, (std::min)(a.second, b.second) + 1) < 0;
auto stra = buf_->data() + a.first;
auto strb = buf_->data() + b.first;
auto cr = memcmp(stra, strb, (std::min)(a.second, b.second) + 1);
return cr < 0 || (cr == 0 && a.second < b.second);
}
const std::vector<uint8_t> *buf_;
};
@@ -1627,8 +1645,249 @@ class Builder FLATBUFFERS_FINAL_CLASS {
KeyOffsetMap key_pool;
StringOffsetMap string_pool;
friend class Verifier;
};
// Helper class to verify the integrity of a FlexBuffer
class Verifier FLATBUFFERS_FINAL_CLASS {
public:
Verifier(const uint8_t *buf, size_t buf_len,
// Supplying this vector likely results in faster verification
// of larger buffers with many shared keys/strings, but
// comes at the cost of using additional memory the same size of
// the buffer being verified, so it is by default off.
std::vector<uint8_t> *reuse_tracker = nullptr,
bool _check_alignment = true, size_t max_depth = 64)
: buf_(buf),
size_(buf_len),
depth_(0),
max_depth_(max_depth),
num_vectors_(0),
max_vectors_(buf_len),
check_alignment_(_check_alignment),
reuse_tracker_(reuse_tracker) {
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
if (reuse_tracker_) {
reuse_tracker_->clear();
reuse_tracker_->resize(size_, PackedType(BIT_WIDTH_8, FBT_NULL));
}
}
private:
// Central location where any verification failures register.
bool Check(bool ok) const {
// clang-format off
#ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
FLATBUFFERS_ASSERT(ok);
#endif
// clang-format on
return ok;
}
// Verify any range within the buffer.
bool VerifyFrom(size_t elem, size_t elem_len) const {
return Check(elem_len < size_ && elem <= size_ - elem_len);
}
bool VerifyBefore(size_t elem, size_t elem_len) const {
return Check(elem_len <= elem);
}
bool VerifyFromPointer(const uint8_t *p, size_t len) {
auto o = static_cast<size_t>(p - buf_);
return VerifyFrom(o, len);
}
bool VerifyBeforePointer(const uint8_t *p, size_t len) {
auto o = static_cast<size_t>(p - buf_);
return VerifyBefore(o, len);
}
bool VerifyByteWidth(size_t width) {
return Check(width == 1 || width == 2 || width == 4 || width == 8);
}
bool VerifyType(int type) { return Check(type >= 0 && type < FBT_MAX_TYPE); }
bool VerifyOffset(uint64_t off, const uint8_t *p) {
return Check(off <= static_cast<uint64_t>(size_)) &&
off <= static_cast<uint64_t>(p - buf_);
}
bool VerifyAlignment(const uint8_t *p, size_t size) const {
auto o = static_cast<size_t>(p - buf_);
return Check((o & (size - 1)) == 0 || !check_alignment_);
}
// Macro, since we want to escape from parent function & use lazy args.
#define FLEX_CHECK_VERIFIED(P, PACKED_TYPE) \
if (reuse_tracker_) { \
auto packed_type = PACKED_TYPE; \
auto existing = (*reuse_tracker_)[P - buf_]; \
if (existing == packed_type) return true; \
/* Fail verification if already set with different type! */ \
if (!Check(existing == 0)) return false; \
(*reuse_tracker_)[P - buf_] = packed_type; \
}
bool VerifyVector(Reference r, const uint8_t *p, Type elem_type) {
// Any kind of nesting goes thru this function, so guard against that
// here, both with simple nesting checks, and the reuse tracker if on.
depth_++;
num_vectors_++;
if (!Check(depth_ <= max_depth_ && num_vectors_ <= max_vectors_))
return false;
auto size_byte_width = r.byte_width_;
FLEX_CHECK_VERIFIED(p,
PackedType(Builder::WidthB(size_byte_width), r.type_));
if (!VerifyBeforePointer(p, size_byte_width)) return false;
auto sized = Sized(p, size_byte_width);
auto num_elems = sized.size();
auto elem_byte_width = r.type_ == FBT_STRING || r.type_ == FBT_BLOB
? uint8_t(1)
: r.byte_width_;
auto max_elems = SIZE_MAX / elem_byte_width;
if (!Check(num_elems < max_elems))
return false; // Protect against byte_size overflowing.
auto byte_size = num_elems * elem_byte_width;
if (!VerifyFromPointer(p, byte_size)) return false;
if (elem_type == FBT_NULL) {
// Verify type bytes after the vector.
if (!VerifyFromPointer(p + byte_size, num_elems)) return false;
auto v = Vector(p, size_byte_width);
for (size_t i = 0; i < num_elems; i++)
if (!VerifyRef(v[i])) return false;
} else if (elem_type == FBT_KEY) {
auto v = TypedVector(p, elem_byte_width, FBT_KEY);
for (size_t i = 0; i < num_elems; i++)
if (!VerifyRef(v[i])) return false;
} else {
FLATBUFFERS_ASSERT(IsInline(elem_type));
}
depth_--;
return true;
}
bool VerifyKeys(const uint8_t *p, uint8_t byte_width) {
// The vector part of the map has already been verified.
const size_t num_prefixed_fields = 3;
if (!VerifyBeforePointer(p, byte_width * num_prefixed_fields)) return false;
p -= byte_width * num_prefixed_fields;
auto off = ReadUInt64(p, byte_width);
if (!VerifyOffset(off, p)) return false;
auto key_byte_with =
static_cast<uint8_t>(ReadUInt64(p + byte_width, byte_width));
if (!VerifyByteWidth(key_byte_with)) return false;
return VerifyVector(Reference(p, byte_width, key_byte_with, FBT_VECTOR_KEY),
p - off, FBT_KEY);
}
bool VerifyKey(const uint8_t *p) {
FLEX_CHECK_VERIFIED(p, PackedType(BIT_WIDTH_8, FBT_KEY));
while (p < buf_ + size_)
if (*p++) return true;
return false;
}
#undef FLEX_CHECK_VERIFIED
bool VerifyTerminator(const String &s) {
return VerifyFromPointer(reinterpret_cast<const uint8_t *>(s.c_str()),
s.size() + 1);
}
bool VerifyRef(Reference r) {
// r.parent_width_ and r.data_ already verified.
if (!VerifyByteWidth(r.byte_width_) || !VerifyType(r.type_)) {
return false;
}
if (IsInline(r.type_)) {
// Inline scalars, don't require further verification.
return true;
}
// All remaining types are an offset.
auto off = ReadUInt64(r.data_, r.parent_width_);
if (!VerifyOffset(off, r.data_)) return false;
auto p = r.Indirect();
if (!VerifyAlignment(p, r.byte_width_)) return false;
switch (r.type_) {
case FBT_INDIRECT_INT:
case FBT_INDIRECT_UINT:
case FBT_INDIRECT_FLOAT: return VerifyFromPointer(p, r.byte_width_);
case FBT_KEY: return VerifyKey(p);
case FBT_MAP:
return VerifyVector(r, p, FBT_NULL) && VerifyKeys(p, r.byte_width_);
case FBT_VECTOR: return VerifyVector(r, p, FBT_NULL);
case FBT_VECTOR_INT: return VerifyVector(r, p, FBT_INT);
case FBT_VECTOR_BOOL:
case FBT_VECTOR_UINT: return VerifyVector(r, p, FBT_UINT);
case FBT_VECTOR_FLOAT: return VerifyVector(r, p, FBT_FLOAT);
case FBT_VECTOR_KEY: return VerifyVector(r, p, FBT_KEY);
case FBT_VECTOR_STRING_DEPRECATED:
// Use of FBT_KEY here intentional, see elsewhere.
return VerifyVector(r, p, FBT_KEY);
case FBT_BLOB: return VerifyVector(r, p, FBT_UINT);
case FBT_STRING:
return VerifyVector(r, p, FBT_UINT) &&
VerifyTerminator(String(p, r.byte_width_));
case FBT_VECTOR_INT2:
case FBT_VECTOR_UINT2:
case FBT_VECTOR_FLOAT2:
case FBT_VECTOR_INT3:
case FBT_VECTOR_UINT3:
case FBT_VECTOR_FLOAT3:
case FBT_VECTOR_INT4:
case FBT_VECTOR_UINT4:
case FBT_VECTOR_FLOAT4: {
uint8_t len = 0;
auto vtype = ToFixedTypedVectorElementType(r.type_, &len);
if (!VerifyType(vtype)) return false;
return VerifyFromPointer(p, r.byte_width_ * len);
}
default: return false;
}
}
public:
bool VerifyBuffer() {
if (!Check(size_ >= 3)) return false;
auto end = buf_ + size_;
auto byte_width = *--end;
auto packed_type = *--end;
return VerifyByteWidth(byte_width) && Check(end - buf_ >= byte_width) &&
VerifyRef(Reference(end - byte_width, byte_width, packed_type));
}
private:
const uint8_t *buf_;
size_t size_;
size_t depth_;
const size_t max_depth_;
size_t num_vectors_;
const size_t max_vectors_;
bool check_alignment_;
std::vector<uint8_t> *reuse_tracker_;
};
// Utility function that contructs the Verifier for you, see above for
// parameters.
inline bool VerifyBuffer(const uint8_t *buf, size_t buf_len,
std::vector<uint8_t> *reuse_tracker = nullptr) {
Verifier verifier(buf, buf_len, reuse_tracker);
return verifier.VerifyBuffer();
}
#ifdef FLATBUFFERS_H_
// This is a verifier utility function that works together with the
// FlatBuffers verifier, which should only be present if flatbuffer.h
// has been included (which it typically is in generated code).
inline bool VerifyNestedFlexBuffer(const flatbuffers::Vector<uint8_t> *nv,
flatbuffers::Verifier &verifier) {
if (!nv) return true;
return verifier.Check(flexbuffers::VerifyBuffer(
nv->data(), nv->size(), verifier.GetFlexReuseTracker()));
}
#endif
} // namespace flexbuffers
#if defined(_MSC_VER)

View File

@@ -72,8 +72,8 @@ namespace flatbuffers {
// - Go type.
// - C# / .Net type.
// - Python type.
// - Rust type.
// - Kotlin type.
// - Rust type.
// using these macros, we can now write code dealing with types just once, e.g.
@@ -468,6 +468,10 @@ inline bool IsUnion(const Type &type) {
return type.enum_def != nullptr && type.enum_def->is_union;
}
inline bool IsUnionType(const Type &type) {
return IsUnion(type) && IsInteger(type.base_type);
}
inline bool IsVector(const Type &type) {
return type.base_type == BASE_TYPE_VECTOR;
}
@@ -591,10 +595,12 @@ struct IDLOptions {
std::string filename_suffix;
std::string filename_extension;
bool no_warnings;
bool warnings_as_errors;
std::string project_root;
bool cs_global_alias;
bool json_nested_flatbuffers;
bool json_nested_flexbuffers;
bool json_nested_legacy_flatbuffers;
// Possible options for the more general generator below.
enum Language {
@@ -624,6 +630,12 @@ struct IDLOptions {
// If set, require all fields in a table to be explicitly numbered.
bool require_explicit_ids;
// If set, implement serde::Serialize for generated Rust types
bool rust_serialize;
// If set, generate rust types in individual files with a root module file.
bool rust_module_root_file;
// The corresponding language bit will be set if a language is included
// for code generation.
unsigned long lang_to_generate;
@@ -680,12 +692,16 @@ struct IDLOptions {
filename_suffix("_generated"),
filename_extension(),
no_warnings(false),
warnings_as_errors(false),
project_root(""),
cs_global_alias(false),
json_nested_flatbuffers(true),
json_nested_flexbuffers(true),
json_nested_legacy_flatbuffers(false),
mini_reflect(IDLOptions::kNone),
require_explicit_ids(false),
rust_serialize(false),
rust_module_root_file(false),
lang_to_generate(0),
set_empty_strings_to_null(true),
set_empty_vectors_to_null(true) {}
@@ -785,6 +801,7 @@ class Parser : public ParserState {
root_struct_def_(nullptr),
opts(options),
uses_flexbuffers_(false),
has_warning_(false),
advanced_features_(0),
source_(nullptr),
anonymous_counter_(0),
@@ -1019,6 +1036,7 @@ class Parser : public ParserState {
IDLOptions opts;
bool uses_flexbuffers_;
bool has_warning_;
uint64_t advanced_features_;

View File

@@ -188,12 +188,12 @@ struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
}
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) &&
VerifyField<uint32_t>(verifier, VT_BASE_SIZE) &&
VerifyField<uint32_t>(verifier, VT_ELEMENT_SIZE) &&
VerifyField<int8_t>(verifier, VT_BASE_TYPE, 1) &&
VerifyField<int8_t>(verifier, VT_ELEMENT, 1) &&
VerifyField<int32_t>(verifier, VT_INDEX, 4) &&
VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH, 2) &&
VerifyField<uint32_t>(verifier, VT_BASE_SIZE, 4) &&
VerifyField<uint32_t>(verifier, VT_ELEMENT_SIZE, 4) &&
verifier.EndTable();
}
};
@@ -261,8 +261,8 @@ struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool KeyCompareLessThan(const KeyValue *o) const {
return *key() < *o->key();
}
int KeyCompareWithValue(const char *val) const {
return strcmp(key()->c_str(), val);
int KeyCompareWithValue(const char *_key) const {
return strcmp(key()->c_str(), _key);
}
const flatbuffers::String *value() const {
return GetPointer<const flatbuffers::String *>(VT_VALUE);
@@ -338,8 +338,8 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
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);
int KeyCompareWithValue(int64_t _value) const {
return static_cast<int>(value() > _value) - static_cast<int>(value() < _value);
}
const reflection::Type *union_type() const {
return GetPointer<const reflection::Type *>(VT_UNION_TYPE);
@@ -351,7 +351,7 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
return VerifyTableStart(verifier) &&
VerifyOffsetRequired(verifier, VT_NAME) &&
verifier.VerifyString(name()) &&
VerifyField<int64_t>(verifier, VT_VALUE) &&
VerifyField<int64_t>(verifier, VT_VALUE, 8) &&
VerifyOffset(verifier, VT_UNION_TYPE) &&
verifier.VerifyTable(union_type()) &&
VerifyOffset(verifier, VT_DOCUMENTATION) &&
@@ -436,8 +436,8 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool KeyCompareLessThan(const Enum *o) const {
return *name() < *o->name();
}
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
int KeyCompareWithValue(const char *_name) const {
return strcmp(name()->c_str(), _name);
}
const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *values() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *>(VT_VALUES);
@@ -465,7 +465,7 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyOffsetRequired(verifier, VT_VALUES) &&
verifier.VerifyVector(values()) &&
verifier.VerifyVectorOfTables(values()) &&
VerifyField<uint8_t>(verifier, VT_IS_UNION) &&
VerifyField<uint8_t>(verifier, VT_IS_UNION, 1) &&
VerifyOffsetRequired(verifier, VT_UNDERLYING_TYPE) &&
verifier.VerifyTable(underlying_type()) &&
VerifyOffset(verifier, VT_ATTRIBUTES) &&
@@ -587,8 +587,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool KeyCompareLessThan(const Field *o) const {
return *name() < *o->name();
}
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
int KeyCompareWithValue(const char *_name) const {
return strcmp(name()->c_str(), _name);
}
const reflection::Type *type() const {
return GetPointer<const reflection::Type *>(VT_TYPE);
@@ -633,21 +633,21 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
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) &&
VerifyField<uint16_t>(verifier, VT_ID, 2) &&
VerifyField<uint16_t>(verifier, VT_OFFSET, 2) &&
VerifyField<int64_t>(verifier, VT_DEFAULT_INTEGER, 8) &&
VerifyField<double>(verifier, VT_DEFAULT_REAL, 8) &&
VerifyField<uint8_t>(verifier, VT_DEPRECATED, 1) &&
VerifyField<uint8_t>(verifier, VT_REQUIRED, 1) &&
VerifyField<uint8_t>(verifier, VT_KEY, 1) &&
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) &&
VerifyField<uint16_t>(verifier, VT_PADDING) &&
VerifyField<uint8_t>(verifier, VT_OPTIONAL, 1) &&
VerifyField<uint16_t>(verifier, VT_PADDING, 2) &&
verifier.EndTable();
}
};
@@ -793,8 +793,8 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool KeyCompareLessThan(const Object *o) const {
return *name() < *o->name();
}
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
int KeyCompareWithValue(const char *_name) const {
return strcmp(name()->c_str(), _name);
}
const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *fields() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *>(VT_FIELDS);
@@ -825,9 +825,9 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
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) &&
VerifyField<uint8_t>(verifier, VT_IS_STRUCT, 1) &&
VerifyField<int32_t>(verifier, VT_MINALIGN, 4) &&
VerifyField<int32_t>(verifier, VT_BYTESIZE, 4) &&
VerifyOffset(verifier, VT_ATTRIBUTES) &&
verifier.VerifyVector(attributes()) &&
verifier.VerifyVectorOfTables(attributes()) &&
@@ -945,8 +945,8 @@ struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool KeyCompareLessThan(const RPCCall *o) const {
return *name() < *o->name();
}
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
int KeyCompareWithValue(const char *_name) const {
return strcmp(name()->c_str(), _name);
}
const reflection::Object *request() const {
return GetPointer<const reflection::Object *>(VT_REQUEST);
@@ -1061,8 +1061,8 @@ struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool KeyCompareLessThan(const Service *o) const {
return *name() < *o->name();
}
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
int KeyCompareWithValue(const char *_name) const {
return strcmp(name()->c_str(), _name);
}
const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *calls() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *>(VT_CALLS);
@@ -1180,8 +1180,8 @@ struct SchemaFile FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool KeyCompareLessThan(const SchemaFile *o) const {
return *filename() < *o->filename();
}
int KeyCompareWithValue(const char *val) const {
return strcmp(filename()->c_str(), val);
int KeyCompareWithValue(const char *_filename) const {
return strcmp(filename()->c_str(), _filename);
}
/// Names of included files, relative to project root.
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *included_filenames() const {
@@ -1297,7 +1297,7 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyOffset(verifier, VT_SERVICES) &&
verifier.VerifyVector(services()) &&
verifier.VerifyVectorOfTables(services()) &&
VerifyField<uint64_t>(verifier, VT_ADVANCED_FEATURES) &&
VerifyField<uint64_t>(verifier, VT_ADVANCED_FEATURES, 8) &&
VerifyOffset(verifier, VT_FBS_FILES) &&
verifier.VerifyVector(fbs_files()) &&
verifier.VerifyVectorOfTables(fbs_files()) &&
@@ -1413,6 +1413,11 @@ inline bool SchemaBufferHasIdentifier(const void *buf) {
buf, SchemaIdentifier());
}
inline bool SizePrefixedSchemaBufferHasIdentifier(const void *buf) {
return flatbuffers::BufferHasIdentifier(
buf, SchemaIdentifier(), true);
}
inline bool VerifySchemaBuffer(
flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier());

View File

@@ -112,20 +112,22 @@ class Table {
// Verify a particular field.
template<typename T>
bool VerifyField(const Verifier &verifier, voffset_t field) const {
bool VerifyField(const Verifier &verifier, voffset_t field,
size_t align) const {
// Calling GetOptionalFieldOffset should be safe now thanks to
// VerifyTable().
auto field_offset = GetOptionalFieldOffset(field);
// Check the actual field.
return !field_offset || verifier.Verify<T>(data_, field_offset);
return !field_offset || verifier.VerifyField<T>(data_, field_offset, align);
}
// VerifyField for required fields.
template<typename T>
bool VerifyFieldRequired(const Verifier &verifier, voffset_t field) const {
bool VerifyFieldRequired(const Verifier &verifier, voffset_t field,
size_t align) const {
auto field_offset = GetOptionalFieldOffset(field);
return verifier.Check(field_offset != 0) &&
verifier.Verify<T>(data_, field_offset);
verifier.VerifyField<T>(data_, field_offset, align);
}
// Versions for offsets.
@@ -163,4 +165,4 @@ inline flatbuffers::Optional<bool> Table::GetOptional<uint8_t, bool>(
} // namespace flatbuffers
#endif // FLATBUFFERS_TABLE_H_
#endif // FLATBUFFERS_TABLE_H_

View File

@@ -17,19 +17,20 @@
#ifndef FLATBUFFERS_UTIL_H_
#define FLATBUFFERS_UTIL_H_
#include <ctype.h>
#include <errno.h>
#include "flatbuffers/base.h"
#include "flatbuffers/stl_emulation.h"
#ifndef FLATBUFFERS_PREFER_PRINTF
# include <iomanip>
# include <sstream>
#else // FLATBUFFERS_PREFER_PRINTF
# include <float.h>
# include <stdio.h>
#endif // FLATBUFFERS_PREFER_PRINTF
#include <iomanip>
#include <string>
namespace flatbuffers {
@@ -94,7 +95,7 @@ template<typename T> size_t IntToDigitCount(T t) {
// 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();
T eps = std::numeric_limits<T>::epsilon();
while (t <= (-1 + eps) || (1 - eps) <= t) {
t /= 10;
digit_count++;

View File

@@ -35,7 +35,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
num_tables_(0),
max_tables_(_max_tables),
upper_bound_(0),
check_alignment_(_check_alignment) {
check_alignment_(_check_alignment),
flex_reuse_tracker_(nullptr) {
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
}
@@ -65,13 +66,13 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return Check(elem_len < size_ && elem <= size_ - elem_len);
}
template<typename T> bool VerifyAlignment(size_t elem) const {
return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_);
bool VerifyAlignment(size_t elem, size_t align) const {
return Check((elem & (align - 1)) == 0 || !check_alignment_);
}
// Verify a range indicated by sizeof(T).
template<typename T> bool Verify(size_t elem) const {
return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T));
return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T));
}
bool VerifyFromPointer(const uint8_t *p, size_t len) {
@@ -80,13 +81,17 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
}
// Verify relative to a known-good base pointer.
bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const {
return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len);
bool VerifyFieldStruct(const uint8_t *base, voffset_t elem_off,
size_t elem_len, size_t align) const {
auto f = static_cast<size_t>(base - buf_) + elem_off;
return VerifyAlignment(f, align) && Verify(f, elem_len);
}
template<typename T>
bool Verify(const uint8_t *base, voffset_t elem_off) const {
return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T));
bool VerifyField(const uint8_t *base, voffset_t elem_off,
size_t align) const {
auto f = static_cast<size_t>(base - buf_) + elem_off;
return VerifyAlignment(f, align) && Verify(f, sizeof(T));
}
// Verify a pointer (may be NULL) of a table type.
@@ -161,7 +166,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table));
// Check the vtable size field, then check vtable fits in its entirety.
return VerifyComplexity() && Verify<voffset_t>(vtableo) &&
VerifyAlignment<voffset_t>(ReadScalar<voffset_t>(buf_ + vtableo)) &&
VerifyAlignment(ReadScalar<voffset_t>(buf_ + vtableo),
sizeof(voffset_t)) &&
Verify(vtableo, ReadScalar<voffset_t>(buf_ + vtableo));
}
@@ -254,6 +260,12 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
// clang-format on
}
std::vector<uint8_t> *GetFlexReuseTracker() { return flex_reuse_tracker_; }
void SetFlexReuseTracker(std::vector<uint8_t> *rt) {
flex_reuse_tracker_ = rt;
}
private:
const uint8_t *buf_;
size_t size_;
@@ -263,6 +275,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
uoffset_t max_tables_;
mutable size_t upper_bound_;
bool check_alignment_;
std::vector<uint8_t> *flex_reuse_tracker_;
};
} // namespace flatbuffers

View File

@@ -763,7 +763,7 @@ public class FlexBuffersBuilder {
// Compute relative offset.
long offset = offsetLoc - iValue;
// Does it fit?
int bitWidth = widthUInBits((int) offset);
int bitWidth = widthUInBits(offset);
if (((1L) << bitWidth) == byteWidth)
return bitWidth;
}

View File

@@ -1,33 +1,3 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
package com.google.flatbuffers;
import java.nio.ByteBuffer;

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TargetFrameworks>netstandard2.1;netstandard2.0;net46</TargetFrameworks>

View File

@@ -0,0 +1,10 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
# New schema language features that are not supported by old code generators.
class AdvancedFeatures(object):
AdvancedArrayFeatures = 1
AdvancedUnionFeatures = 2
OptionalScalars = 4
DefaultVectorsAndStrings = 8

View File

@@ -0,0 +1,24 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
class BaseType(object):
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

View File

@@ -0,0 +1,169 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class Enum(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = Enum()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsEnum(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def EnumBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# Enum
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# Enum
def Name(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# Enum
def Values(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.EnumVal import EnumVal
obj = EnumVal()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Enum
def ValuesLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Enum
def ValuesIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
return o == 0
# Enum
def IsUnion(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
return False
# Enum
def UnderlyingType(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
from reflection.Type import Type
obj = Type()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Enum
def Attributes(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.KeyValue import KeyValue
obj = KeyValue()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Enum
def AttributesLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Enum
def AttributesIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
return o == 0
# Enum
def Documentation(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
a = self._tab.Vector(o)
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
return ""
# Enum
def DocumentationLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Enum
def DocumentationIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
return o == 0
# File that this Enum is declared in.
# Enum
def DeclarationFile(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
def EnumStart(builder): builder.StartObject(7)
def Start(builder):
return EnumStart(builder)
def EnumAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
def AddName(builder, name):
return EnumAddName(builder, name)
def EnumAddValues(builder, values): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(values), 0)
def AddValues(builder, values):
return EnumAddValues(builder, values)
def EnumStartValuesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartValuesVector(builder, numElems):
return EnumStartValuesVector(builder, numElems)
def EnumAddIsUnion(builder, isUnion): builder.PrependBoolSlot(2, isUnion, 0)
def AddIsUnion(builder, isUnion):
return EnumAddIsUnion(builder, isUnion)
def EnumAddUnderlyingType(builder, underlyingType): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(underlyingType), 0)
def AddUnderlyingType(builder, underlyingType):
return EnumAddUnderlyingType(builder, underlyingType)
def EnumAddAttributes(builder, attributes): builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
def AddAttributes(builder, attributes):
return EnumAddAttributes(builder, attributes)
def EnumStartAttributesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartAttributesVector(builder, numElems):
return EnumStartAttributesVector(builder, numElems)
def EnumAddDocumentation(builder, documentation): builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
def AddDocumentation(builder, documentation):
return EnumAddDocumentation(builder, documentation)
def EnumStartDocumentationVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartDocumentationVector(builder, numElems):
return EnumStartDocumentationVector(builder, numElems)
def EnumAddDeclarationFile(builder, declarationFile): builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
def AddDeclarationFile(builder, declarationFile):
return EnumAddDeclarationFile(builder, declarationFile)
def EnumEnd(builder): return builder.EndObject()
def End(builder):
return EnumEnd(builder)

View File

@@ -0,0 +1,96 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class EnumVal(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = EnumVal()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsEnumVal(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def EnumValBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# EnumVal
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# EnumVal
def Name(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# EnumVal
def Value(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
return 0
# EnumVal
def UnionType(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
from reflection.Type import Type
obj = Type()
obj.Init(self._tab.Bytes, x)
return obj
return None
# EnumVal
def Documentation(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
a = self._tab.Vector(o)
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
return ""
# EnumVal
def DocumentationLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
return self._tab.VectorLen(o)
return 0
# EnumVal
def DocumentationIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
return o == 0
def EnumValStart(builder): builder.StartObject(5)
def Start(builder):
return EnumValStart(builder)
def EnumValAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
def AddName(builder, name):
return EnumValAddName(builder, name)
def EnumValAddValue(builder, value): builder.PrependInt64Slot(1, value, 0)
def AddValue(builder, value):
return EnumValAddValue(builder, value)
def EnumValAddUnionType(builder, unionType): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(unionType), 0)
def AddUnionType(builder, unionType):
return EnumValAddUnionType(builder, unionType)
def EnumValAddDocumentation(builder, documentation): builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
def AddDocumentation(builder, documentation):
return EnumValAddDocumentation(builder, documentation)
def EnumValStartDocumentationVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartDocumentationVector(builder, numElems):
return EnumValStartDocumentationVector(builder, numElems)
def EnumValEnd(builder): return builder.EndObject()
def End(builder):
return EnumValEnd(builder)

View File

@@ -0,0 +1,208 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class Field(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = Field()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsField(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def FieldBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# Field
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# Field
def Name(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# Field
def Type(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
from reflection.Type import Type
obj = Type()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Field
def Id(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
return 0
# Field
def Offset(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
return 0
# Field
def DefaultInteger(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
return 0
# Field
def DefaultReal(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
return 0.0
# Field
def Deprecated(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
if o != 0:
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
return False
# Field
def Required(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
if o != 0:
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
return False
# Field
def Key(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
if o != 0:
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
return False
# Field
def Attributes(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.KeyValue import KeyValue
obj = KeyValue()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Field
def AttributesLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Field
def AttributesIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
return o == 0
# Field
def Documentation(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
if o != 0:
a = self._tab.Vector(o)
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
return ""
# Field
def DocumentationLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Field
def DocumentationIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
return o == 0
# Field
def Optional(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
if o != 0:
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
return False
# Number of padding octets to always add after this field. Structs only.
# Field
def Padding(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
return 0
def FieldStart(builder): builder.StartObject(13)
def Start(builder):
return FieldStart(builder)
def FieldAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
def AddName(builder, name):
return FieldAddName(builder, name)
def FieldAddType(builder, type): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(type), 0)
def AddType(builder, type):
return FieldAddType(builder, type)
def FieldAddId(builder, id): builder.PrependUint16Slot(2, id, 0)
def AddId(builder, id):
return FieldAddId(builder, id)
def FieldAddOffset(builder, offset): builder.PrependUint16Slot(3, offset, 0)
def AddOffset(builder, offset):
return FieldAddOffset(builder, offset)
def FieldAddDefaultInteger(builder, defaultInteger): builder.PrependInt64Slot(4, defaultInteger, 0)
def AddDefaultInteger(builder, defaultInteger):
return FieldAddDefaultInteger(builder, defaultInteger)
def FieldAddDefaultReal(builder, defaultReal): builder.PrependFloat64Slot(5, defaultReal, 0.0)
def AddDefaultReal(builder, defaultReal):
return FieldAddDefaultReal(builder, defaultReal)
def FieldAddDeprecated(builder, deprecated): builder.PrependBoolSlot(6, deprecated, 0)
def AddDeprecated(builder, deprecated):
return FieldAddDeprecated(builder, deprecated)
def FieldAddRequired(builder, required): builder.PrependBoolSlot(7, required, 0)
def AddRequired(builder, required):
return FieldAddRequired(builder, required)
def FieldAddKey(builder, key): builder.PrependBoolSlot(8, key, 0)
def AddKey(builder, key):
return FieldAddKey(builder, key)
def FieldAddAttributes(builder, attributes): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
def AddAttributes(builder, attributes):
return FieldAddAttributes(builder, attributes)
def FieldStartAttributesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartAttributesVector(builder, numElems):
return FieldStartAttributesVector(builder, numElems)
def FieldAddDocumentation(builder, documentation): builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
def AddDocumentation(builder, documentation):
return FieldAddDocumentation(builder, documentation)
def FieldStartDocumentationVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartDocumentationVector(builder, numElems):
return FieldStartDocumentationVector(builder, numElems)
def FieldAddOptional(builder, optional): builder.PrependBoolSlot(11, optional, 0)
def AddOptional(builder, optional):
return FieldAddOptional(builder, optional)
def FieldAddPadding(builder, padding): builder.PrependUint16Slot(12, padding, 0)
def AddPadding(builder, padding):
return FieldAddPadding(builder, padding)
def FieldEnd(builder): return builder.EndObject()
def End(builder):
return FieldEnd(builder)

View File

@@ -0,0 +1,56 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class KeyValue(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = KeyValue()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsKeyValue(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def KeyValueBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# KeyValue
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# KeyValue
def Key(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# KeyValue
def Value(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
def KeyValueStart(builder): builder.StartObject(2)
def Start(builder):
return KeyValueStart(builder)
def KeyValueAddKey(builder, key): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(key), 0)
def AddKey(builder, key):
return KeyValueAddKey(builder, key)
def KeyValueAddValue(builder, value): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(value), 0)
def AddValue(builder, value):
return KeyValueAddValue(builder, value)
def KeyValueEnd(builder): return builder.EndObject()
def End(builder):
return KeyValueEnd(builder)

View File

@@ -0,0 +1,175 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class Object(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = Object()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsObject(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def ObjectBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# Object
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# Object
def Name(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# Object
def Fields(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.Field import Field
obj = Field()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Object
def FieldsLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Object
def FieldsIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
return o == 0
# Object
def IsStruct(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
return False
# Object
def Minalign(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
return 0
# Object
def Bytesize(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
return 0
# Object
def Attributes(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.KeyValue import KeyValue
obj = KeyValue()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Object
def AttributesLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Object
def AttributesIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
return o == 0
# Object
def Documentation(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
if o != 0:
a = self._tab.Vector(o)
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
return ""
# Object
def DocumentationLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Object
def DocumentationIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
return o == 0
# File that this Object is declared in.
# Object
def DeclarationFile(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
def ObjectStart(builder): builder.StartObject(8)
def Start(builder):
return ObjectStart(builder)
def ObjectAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
def AddName(builder, name):
return ObjectAddName(builder, name)
def ObjectAddFields(builder, fields): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(fields), 0)
def AddFields(builder, fields):
return ObjectAddFields(builder, fields)
def ObjectStartFieldsVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartFieldsVector(builder, numElems):
return ObjectStartFieldsVector(builder, numElems)
def ObjectAddIsStruct(builder, isStruct): builder.PrependBoolSlot(2, isStruct, 0)
def AddIsStruct(builder, isStruct):
return ObjectAddIsStruct(builder, isStruct)
def ObjectAddMinalign(builder, minalign): builder.PrependInt32Slot(3, minalign, 0)
def AddMinalign(builder, minalign):
return ObjectAddMinalign(builder, minalign)
def ObjectAddBytesize(builder, bytesize): builder.PrependInt32Slot(4, bytesize, 0)
def AddBytesize(builder, bytesize):
return ObjectAddBytesize(builder, bytesize)
def ObjectAddAttributes(builder, attributes): builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
def AddAttributes(builder, attributes):
return ObjectAddAttributes(builder, attributes)
def ObjectStartAttributesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartAttributesVector(builder, numElems):
return ObjectStartAttributesVector(builder, numElems)
def ObjectAddDocumentation(builder, documentation): builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
def AddDocumentation(builder, documentation):
return ObjectAddDocumentation(builder, documentation)
def ObjectStartDocumentationVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartDocumentationVector(builder, numElems):
return ObjectStartDocumentationVector(builder, numElems)
def ObjectAddDeclarationFile(builder, declarationFile): builder.PrependUOffsetTRelativeSlot(7, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
def AddDeclarationFile(builder, declarationFile):
return ObjectAddDeclarationFile(builder, declarationFile)
def ObjectEnd(builder): return builder.EndObject()
def End(builder):
return ObjectEnd(builder)

View File

@@ -0,0 +1,131 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class RPCCall(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = RPCCall()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsRPCCall(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def RPCCallBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# RPCCall
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# RPCCall
def Name(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# RPCCall
def Request(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
from reflection.Object import Object
obj = Object()
obj.Init(self._tab.Bytes, x)
return obj
return None
# RPCCall
def Response(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
from reflection.Object import Object
obj = Object()
obj.Init(self._tab.Bytes, x)
return obj
return None
# RPCCall
def Attributes(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.KeyValue import KeyValue
obj = KeyValue()
obj.Init(self._tab.Bytes, x)
return obj
return None
# RPCCall
def AttributesLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
return self._tab.VectorLen(o)
return 0
# RPCCall
def AttributesIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
return o == 0
# RPCCall
def Documentation(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
a = self._tab.Vector(o)
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
return ""
# RPCCall
def DocumentationLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
return self._tab.VectorLen(o)
return 0
# RPCCall
def DocumentationIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
return o == 0
def RPCCallStart(builder): builder.StartObject(5)
def Start(builder):
return RPCCallStart(builder)
def RPCCallAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
def AddName(builder, name):
return RPCCallAddName(builder, name)
def RPCCallAddRequest(builder, request): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(request), 0)
def AddRequest(builder, request):
return RPCCallAddRequest(builder, request)
def RPCCallAddResponse(builder, response): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(response), 0)
def AddResponse(builder, response):
return RPCCallAddResponse(builder, response)
def RPCCallAddAttributes(builder, attributes): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
def AddAttributes(builder, attributes):
return RPCCallAddAttributes(builder, attributes)
def RPCCallStartAttributesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartAttributesVector(builder, numElems):
return RPCCallStartAttributesVector(builder, numElems)
def RPCCallAddDocumentation(builder, documentation): builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
def AddDocumentation(builder, documentation):
return RPCCallAddDocumentation(builder, documentation)
def RPCCallStartDocumentationVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartDocumentationVector(builder, numElems):
return RPCCallStartDocumentationVector(builder, numElems)
def RPCCallEnd(builder): return builder.EndObject()
def End(builder):
return RPCCallEnd(builder)

View File

@@ -0,0 +1,206 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class Schema(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = Schema()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsSchema(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def SchemaBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# Schema
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# Schema
def Objects(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.Object import Object
obj = Object()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Schema
def ObjectsLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Schema
def ObjectsIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
return o == 0
# Schema
def Enums(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.Enum import Enum
obj = Enum()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Schema
def EnumsLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Schema
def EnumsIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
return o == 0
# Schema
def FileIdent(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# Schema
def FileExt(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# Schema
def RootTable(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
from reflection.Object import Object
obj = Object()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Schema
def Services(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.Service import Service
obj = Service()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Schema
def ServicesLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Schema
def ServicesIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
return o == 0
# Schema
def AdvancedFeatures(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
return 0
# All the files used in this compilation. Files are relative to where
# flatc was invoked.
# Schema
def FbsFiles(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.SchemaFile import SchemaFile
obj = SchemaFile()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Schema
def FbsFilesLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Schema
def FbsFilesIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
return o == 0
def SchemaStart(builder): builder.StartObject(8)
def Start(builder):
return SchemaStart(builder)
def SchemaAddObjects(builder, objects): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(objects), 0)
def AddObjects(builder, objects):
return SchemaAddObjects(builder, objects)
def SchemaStartObjectsVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartObjectsVector(builder, numElems):
return SchemaStartObjectsVector(builder, numElems)
def SchemaAddEnums(builder, enums): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(enums), 0)
def AddEnums(builder, enums):
return SchemaAddEnums(builder, enums)
def SchemaStartEnumsVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartEnumsVector(builder, numElems):
return SchemaStartEnumsVector(builder, numElems)
def SchemaAddFileIdent(builder, fileIdent): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(fileIdent), 0)
def AddFileIdent(builder, fileIdent):
return SchemaAddFileIdent(builder, fileIdent)
def SchemaAddFileExt(builder, fileExt): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(fileExt), 0)
def AddFileExt(builder, fileExt):
return SchemaAddFileExt(builder, fileExt)
def SchemaAddRootTable(builder, rootTable): builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(rootTable), 0)
def AddRootTable(builder, rootTable):
return SchemaAddRootTable(builder, rootTable)
def SchemaAddServices(builder, services): builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(services), 0)
def AddServices(builder, services):
return SchemaAddServices(builder, services)
def SchemaStartServicesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartServicesVector(builder, numElems):
return SchemaStartServicesVector(builder, numElems)
def SchemaAddAdvancedFeatures(builder, advancedFeatures): builder.PrependUint64Slot(6, advancedFeatures, 0)
def AddAdvancedFeatures(builder, advancedFeatures):
return SchemaAddAdvancedFeatures(builder, advancedFeatures)
def SchemaAddFbsFiles(builder, fbsFiles): builder.PrependUOffsetTRelativeSlot(7, flatbuffers.number_types.UOffsetTFlags.py_type(fbsFiles), 0)
def AddFbsFiles(builder, fbsFiles):
return SchemaAddFbsFiles(builder, fbsFiles)
def SchemaStartFbsFilesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartFbsFilesVector(builder, numElems):
return SchemaStartFbsFilesVector(builder, numElems)
def SchemaEnd(builder): return builder.EndObject()
def End(builder):
return SchemaEnd(builder)

View File

@@ -0,0 +1,77 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
# File specific information.
# Symbols declared within a file may be recovered by iterating over all
# symbols and examining the `declaration_file` field.
class SchemaFile(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = SchemaFile()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsSchemaFile(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def SchemaFileBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# SchemaFile
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# Filename, relative to project root.
# SchemaFile
def Filename(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# Names of included files, relative to project root.
# SchemaFile
def IncludedFilenames(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
a = self._tab.Vector(o)
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
return ""
# SchemaFile
def IncludedFilenamesLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.VectorLen(o)
return 0
# SchemaFile
def IncludedFilenamesIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
return o == 0
def SchemaFileStart(builder): builder.StartObject(2)
def Start(builder):
return SchemaFileStart(builder)
def SchemaFileAddFilename(builder, filename): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(filename), 0)
def AddFilename(builder, filename):
return SchemaFileAddFilename(builder, filename)
def SchemaFileAddIncludedFilenames(builder, includedFilenames): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(includedFilenames), 0)
def AddIncludedFilenames(builder, includedFilenames):
return SchemaFileAddIncludedFilenames(builder, includedFilenames)
def SchemaFileStartIncludedFilenamesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartIncludedFilenamesVector(builder, numElems):
return SchemaFileStartIncludedFilenamesVector(builder, numElems)
def SchemaFileEnd(builder): return builder.EndObject()
def End(builder):
return SchemaFileEnd(builder)

View File

@@ -0,0 +1,145 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class Service(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = Service()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsService(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def ServiceBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# Service
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# Service
def Name(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
# Service
def Calls(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.RPCCall import RPCCall
obj = RPCCall()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Service
def CallsLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Service
def CallsIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
return o == 0
# Service
def Attributes(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
from reflection.KeyValue import KeyValue
obj = KeyValue()
obj.Init(self._tab.Bytes, x)
return obj
return None
# Service
def AttributesLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Service
def AttributesIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
return o == 0
# Service
def Documentation(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
a = self._tab.Vector(o)
return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
return ""
# Service
def DocumentationLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
return self._tab.VectorLen(o)
return 0
# Service
def DocumentationIsNone(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
return o == 0
# File that this Service is declared in.
# Service
def DeclarationFile(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
return self._tab.String(o + self._tab.Pos)
return None
def ServiceStart(builder): builder.StartObject(5)
def Start(builder):
return ServiceStart(builder)
def ServiceAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
def AddName(builder, name):
return ServiceAddName(builder, name)
def ServiceAddCalls(builder, calls): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(calls), 0)
def AddCalls(builder, calls):
return ServiceAddCalls(builder, calls)
def ServiceStartCallsVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartCallsVector(builder, numElems):
return ServiceStartCallsVector(builder, numElems)
def ServiceAddAttributes(builder, attributes): builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
def AddAttributes(builder, attributes):
return ServiceAddAttributes(builder, attributes)
def ServiceStartAttributesVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartAttributesVector(builder, numElems):
return ServiceStartAttributesVector(builder, numElems)
def ServiceAddDocumentation(builder, documentation): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
def AddDocumentation(builder, documentation):
return ServiceAddDocumentation(builder, documentation)
def ServiceStartDocumentationVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def StartDocumentationVector(builder, numElems):
return ServiceStartDocumentationVector(builder, numElems)
def ServiceAddDeclarationFile(builder, declarationFile): builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
def AddDeclarationFile(builder, declarationFile):
return ServiceAddDeclarationFile(builder, declarationFile)
def ServiceEnd(builder): return builder.EndObject()
def End(builder):
return ServiceEnd(builder)

View File

@@ -0,0 +1,98 @@
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: reflection
import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()
class Type(object):
__slots__ = ['_tab']
@classmethod
def GetRootAs(cls, buf, offset=0):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = Type()
x.Init(buf, n + offset)
return x
@classmethod
def GetRootAsType(cls, buf, offset=0):
"""This method is deprecated. Please switch to GetRootAs."""
return cls.GetRootAs(buf, offset)
@classmethod
def TypeBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x42\x46\x42\x53", size_prefixed=size_prefixed)
# Type
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# Type
def BaseType(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
return 0
# Type
def Element(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
return 0
# Type
def Index(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
return -1
# Type
def FixedLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
return 0
# The size (octets) of the `base_type` field.
# Type
def BaseSize(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
return 4
# The size (octets) of the `element` field, if present.
# Type
def ElementSize(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
return 0
def TypeStart(builder): builder.StartObject(6)
def Start(builder):
return TypeStart(builder)
def TypeAddBaseType(builder, baseType): builder.PrependInt8Slot(0, baseType, 0)
def AddBaseType(builder, baseType):
return TypeAddBaseType(builder, baseType)
def TypeAddElement(builder, element): builder.PrependInt8Slot(1, element, 0)
def AddElement(builder, element):
return TypeAddElement(builder, element)
def TypeAddIndex(builder, index): builder.PrependInt32Slot(2, index, -1)
def AddIndex(builder, index):
return TypeAddIndex(builder, index)
def TypeAddFixedLength(builder, fixedLength): builder.PrependUint16Slot(3, fixedLength, 0)
def AddFixedLength(builder, fixedLength):
return TypeAddFixedLength(builder, fixedLength)
def TypeAddBaseSize(builder, baseSize): builder.PrependUint32Slot(4, baseSize, 4)
def AddBaseSize(builder, baseSize):
return TypeAddBaseSize(builder, baseSize)
def TypeAddElementSize(builder, elementSize): builder.PrependUint32Slot(5, elementSize, 0)
def AddElementSize(builder, elementSize):
return TypeAddElementSize(builder, elementSize)
def TypeEnd(builder): return builder.EndObject()
def End(builder):
return TypeEnd(builder)

View File

@@ -1,11 +1,11 @@
![logo](http://google.github.io/flatbuffers/fpl_logo_small.png) FlatBuffers
===========
[![Build Status](https://travis-ci.org/google/flatbuffers.svg?branch=master)](https://travis-ci.org/google/flatbuffers)
[![Build status](https://ci.appveyor.com/api/projects/status/yg5idd2fnusv1n10?svg=true)](https://ci.appveyor.com/project/gwvo/flatbuffers)
![Build status](https://github.com/google/flatbuffers/actions/workflows/build.yml/badge.svg?branch=master)
[![Join the chat at https://gitter.im/google/flatbuffers](https://badges.gitter.im/google/flatbuffers.svg)](https://gitter.im/google/flatbuffers?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Discord Chat](https://img.shields.io/discord/656202785926152206.svg)](https:///discord.gg/6qgKs3R)
[![Twitter Follow](https://img.shields.io/twitter/follow/wvo.svg?style=social)](https://twitter.com/wvo)
[![Twitter Follow](https://img.shields.io/twitter/follow/dbaileychess.svg?style=social)](https://twitter.com/dbaileychess)
**FlatBuffers** is a cross platform serialization library architected for

View File

@@ -1,6 +1,6 @@
[package]
name = "flatbuffers"
version = "2.0.0"
version = "2.1.0"
edition = "2018"
authors = ["Robert Winslow <hello@rwinslow.com>", "FlatBuffers Maintainers"]
license = "Apache-2.0"
@@ -11,7 +11,16 @@ keywords = ["flatbuffers", "serialization", "zero-copy"]
categories = ["encoding", "data-structures", "memory-management"]
rust = "1.51"
[features]
default = ["thiserror"]
no_std = ["core2", "thiserror_core2"]
serialize = ["serde"]
[dependencies]
smallvec = "1.6.1"
bitflags = "1.2.1"
thiserror = "1.0.23"
serde = { version = "1.0", optional = true }
thiserror = { version = "1.0.30", optional = true }
core2 = { version = "0.4.0", optional = true }
# This version is compliant with mainline 1.0.30
thiserror_core2 = { version = "2.0.0", default-features = false, optional = true }

View File

@@ -17,9 +17,9 @@
use crate::follow::Follow;
use crate::vector::VectorIter;
use crate::EndianScalar;
use std::fmt::{Debug, Formatter, Result};
use std::marker::PhantomData;
use std::mem::size_of;
use core::fmt::{Debug, Formatter, Result};
use core::marker::PhantomData;
use core::mem::size_of;
#[derive(Copy, Clone)]
pub struct Array<'a, T: 'a, const N: usize>(&'a [u8], PhantomData<T>);
@@ -133,3 +133,22 @@ where
array.assume_init()
}
}
#[cfg(feature="serialize")]
impl<'a, T: 'a, const N: usize> serde::ser::Serialize for Array<'a, T, N>
where
T: 'a + Follow<'a>,
<T as Follow<'a>>::Inner: serde::ser::Serialize,
{
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for element in self.iter() {
seq.serialize_element(&element)?;
}
seq.end()
}
}

View File

@@ -16,11 +16,13 @@
extern crate smallvec;
use std::cmp::max;
use std::iter::{DoubleEndedIterator, ExactSizeIterator};
use std::marker::PhantomData;
use std::ptr::write_bytes;
use std::slice::from_raw_parts;
use core::cmp::max;
use core::iter::{DoubleEndedIterator, ExactSizeIterator};
use core::marker::PhantomData;
use core::ptr::write_bytes;
use core::slice::from_raw_parts;
#[cfg(feature = "no_std")]
use alloc::{vec, vec::Vec};
use crate::endian_scalar::{emplace_scalar, read_scalar_at};
use crate::primitives::*;

View File

@@ -15,7 +15,7 @@
*/
#![allow(clippy::wrong_self_convention)]
use std::mem::size_of;
use core::mem::size_of;
/// Trait for values that must be stored in little-endian byte order, but
/// might be represented in memory as big-endian. Every type that implements

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
use std::marker::PhantomData;
use core::marker::PhantomData;
/// Follow is a trait that allows us to access FlatBuffers in a declarative,
/// type safe, and fast way. They compile down to almost no code (after

View File

@@ -28,6 +28,11 @@
//! At this time, to generate Rust code, you will need the latest `master` version of `flatc`, available from here: <https://github.com/google/flatbuffers>
//! (On OSX, you can install FlatBuffers from `HEAD` with the Homebrew package manager.)
#![cfg_attr(feature = "no_std", no_std)]
#[cfg(feature = "no_std")]
extern crate alloc;
mod array;
mod builder;
mod endian_scalar;

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
use std::marker::PhantomData;
use std::mem::size_of;
use std::ops::Deref;
use core::marker::PhantomData;
use core::mem::size_of;
use core::ops::Deref;
use crate::endian_scalar::{emplace_scalar, read_scalar, read_scalar_at};
use crate::follow::Follow;

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
use std::cmp::max;
use std::mem::{align_of, size_of};
use core::cmp::max;
use core::mem::{align_of, size_of};
use crate::endian_scalar::emplace_scalar;

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
use std::fmt::{Debug, Formatter, Result};
use std::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
use std::marker::PhantomData;
use std::mem::size_of;
use std::slice::from_raw_parts;
use std::str::from_utf8_unchecked;
use core::fmt::{Debug, Formatter, Result};
use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
use core::marker::PhantomData;
use core::mem::size_of;
use core::slice::from_raw_parts;
use core::str::from_utf8_unchecked;
use crate::endian_scalar::read_scalar_at;
#[cfg(target_endian = "little")]
@@ -308,3 +308,22 @@ impl<'a, 'b, T: Follow<'a> + 'a> IntoIterator for &'b Vector<'a, T> {
self.iter()
}
}
#[cfg(feature="serialize")]
impl<'a, T> serde::ser::Serialize for Vector<'a, T>
where
T: 'a + Follow<'a>,
<T as Follow<'a>>::Inner: serde::ser::Serialize,
{
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for element in self {
seq.serialize_element(&element)?;
}
seq.end()
}
}

View File

@@ -1,6 +1,12 @@
#[cfg(feature = "no_std")]
use alloc::vec::Vec;
use core::ops::Range;
use core::option::Option;
use crate::follow::Follow;
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
use std::ops::Range;
#[cfg(feature="no_std")]
extern crate thiserror_core2 as thiserror;
use thiserror::Error;
/// Traces the location of data errors. Not populated for Dos detecting errors.
@@ -23,7 +29,7 @@ pub enum ErrorTraceDetail {
}
#[derive(PartialEq, Eq, Default, Debug, Clone)]
pub struct ErrorTrace(Vec<ErrorTraceDetail>);
impl std::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
#[inline]
fn as_ref(&self) -> &[ErrorTraceDetail] {
&self.0
@@ -51,7 +57,7 @@ pub enum InvalidFlatbuffer {
#[error("Utf8 error for string in {range:?}: {error}\n{error_trace}")]
Utf8Error {
#[source]
error: std::str::Utf8Error,
error: core::str::Utf8Error,
range: Range<usize>,
error_trace: ErrorTrace,
},
@@ -90,8 +96,8 @@ pub enum InvalidFlatbuffer {
DepthLimitReached,
}
impl std::fmt::Display for ErrorTrace {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
impl core::fmt::Display for ErrorTrace {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
use ErrorTraceDetail::*;
for e in self.0.iter() {
match e {
@@ -125,7 +131,7 @@ impl std::fmt::Display for ErrorTrace {
}
}
pub type Result<T> = std::prelude::v1::Result<T, InvalidFlatbuffer>;
pub type Result<T> = core::result::Result<T, InvalidFlatbuffer>;
impl InvalidFlatbuffer {
fn new_range_oob<T>(start: usize, end: usize) -> Result<T> {
@@ -245,11 +251,11 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
/// `buffer[0]`. TODO(caspern).
#[inline]
fn is_aligned<T>(&self, pos: usize) -> Result<()> {
if pos % std::mem::align_of::<T>() == 0 {
if pos % core::mem::align_of::<T>() == 0 {
Ok(())
} else {
Err(InvalidFlatbuffer::Unaligned {
unaligned_type: std::any::type_name::<T>(),
unaligned_type: core::any::type_name::<T>(),
position: pos,
error_trace: Default::default(),
})
@@ -271,7 +277,7 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
#[inline]
pub fn in_buffer<T>(&mut self, pos: usize) -> Result<()> {
self.is_aligned::<T>(pos)?;
self.range_in_buffer(pos, std::mem::size_of::<T>())
self.range_in_buffer(pos, core::mem::size_of::<T>())
}
#[inline]
fn get_u16(&mut self, pos: usize) -> Result<u16> {
@@ -416,7 +422,7 @@ impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
where
Key: Follow<'buf> + Verifiable,
UnionVerifier:
(std::ops::FnOnce(<Key as Follow<'buf>>::Inner, &mut Verifier, usize) -> Result<()>),
(core::ops::FnOnce(<Key as Follow<'buf>>::Inner, &mut Verifier, usize) -> Result<()>),
// NOTE: <Key as Follow<'buf>>::Inner == Key
{
// TODO(caspern): how to trace vtable errors?
@@ -468,14 +474,14 @@ impl<T: Verifiable> Verifiable for ForwardsUOffset<T> {
}
/// Checks and returns the range containing the flatbuffers vector.
fn verify_vector_range<T>(v: &mut Verifier, pos: usize) -> Result<std::ops::Range<usize>> {
fn verify_vector_range<T>(v: &mut Verifier, pos: usize) -> Result<core::ops::Range<usize>> {
let len = v.get_uoffset(pos)? as usize;
let start = pos.saturating_add(SIZE_UOFFSET);
v.is_aligned::<T>(start)?;
let size = len.saturating_mul(std::mem::size_of::<T>());
let size = len.saturating_mul(core::mem::size_of::<T>());
let end = start.saturating_add(size);
v.range_in_buffer(start, size)?;
Ok(std::ops::Range { start, end })
Ok(core::ops::Range { start, end })
}
pub trait SimpleToVerifyInSlice {}
@@ -509,7 +515,7 @@ impl<T: Verifiable> Verifiable for Vector<'_, ForwardsUOffset<T>> {
#[inline]
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()> {
let range = verify_vector_range::<ForwardsUOffset<T>>(v, pos)?;
let size = std::mem::size_of::<ForwardsUOffset<T>>();
let size = core::mem::size_of::<ForwardsUOffset<T>>();
for (i, element_pos) in range.step_by(size).enumerate() {
trace_elem(
<ForwardsUOffset<T>>::run_verifier(v, element_pos),
@@ -526,7 +532,7 @@ impl<'a> Verifiable for &'a str {
fn run_verifier(v: &mut Verifier, pos: usize) -> Result<()> {
let range = verify_vector_range::<u8>(v, pos)?;
let has_null_terminator = v.buffer.get(range.end).map(|&b| b == 0).unwrap_or(false);
let s = std::str::from_utf8(&v.buffer[range.clone()]);
let s = core::str::from_utf8(&v.buffer[range.clone()]);
if let Err(error) = s {
return Err(InvalidFlatbuffer::Utf8Error {
error,

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
use std::ptr::write_bytes;
use core::ptr::write_bytes;
use crate::endian_scalar::emplace_scalar;
use crate::primitives::*;

View File

@@ -239,6 +239,10 @@ struct MonsterT : public flatbuffers::NativeTable {
std::vector<flatbuffers::unique_ptr<MyGame::Sample::WeaponT>> weapons{};
MyGame::Sample::EquipmentUnion equipped{};
std::vector<MyGame::Sample::Vec3> path{};
MonsterT() = default;
MonsterT(const MonsterT &o);
MonsterT(MonsterT&&) FLATBUFFERS_NOEXCEPT = default;
MonsterT &operator=(MonsterT o) FLATBUFFERS_NOEXCEPT;
};
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@@ -322,18 +326,18 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<MyGame::Sample::Vec3>(verifier, VT_POS) &&
VerifyField<int16_t>(verifier, VT_MANA) &&
VerifyField<int16_t>(verifier, VT_HP) &&
VerifyField<MyGame::Sample::Vec3>(verifier, VT_POS, 4) &&
VerifyField<int16_t>(verifier, VT_MANA, 2) &&
VerifyField<int16_t>(verifier, VT_HP, 2) &&
VerifyOffset(verifier, VT_NAME) &&
verifier.VerifyString(name()) &&
VerifyOffset(verifier, VT_INVENTORY) &&
verifier.VerifyVector(inventory()) &&
VerifyField<int8_t>(verifier, VT_COLOR) &&
VerifyField<int8_t>(verifier, VT_COLOR, 1) &&
VerifyOffset(verifier, VT_WEAPONS) &&
verifier.VerifyVector(weapons()) &&
verifier.VerifyVectorOfTables(weapons()) &&
VerifyField<uint8_t>(verifier, VT_EQUIPPED_TYPE) &&
VerifyField<uint8_t>(verifier, VT_EQUIPPED_TYPE, 1) &&
VerifyOffset(verifier, VT_EQUIPPED) &&
VerifyEquipment(verifier, equipped(), equipped_type()) &&
VerifyOffset(verifier, VT_PATH) &&
@@ -484,7 +488,7 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_NAME) &&
verifier.VerifyString(name()) &&
VerifyField<int16_t>(verifier, VT_DAMAGE) &&
VerifyField<int16_t>(verifier, VT_DAMAGE, 2) &&
verifier.EndTable();
}
WeaponT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
@@ -555,6 +559,32 @@ inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
}
inline MonsterT::MonsterT(const MonsterT &o)
: pos((o.pos) ? new MyGame::Sample::Vec3(*o.pos) : nullptr),
mana(o.mana),
hp(o.hp),
name(o.name),
inventory(o.inventory),
color(o.color),
equipped(o.equipped),
path(o.path) {
weapons.reserve(o.weapons.size());
for (const auto &v : o.weapons) { weapons.emplace_back((v) ? new MyGame::Sample::WeaponT(*v) : nullptr); }
}
inline MonsterT &MonsterT::operator=(MonsterT o) FLATBUFFERS_NOEXCEPT {
std::swap(pos, o.pos);
std::swap(mana, o.mana);
std::swap(hp, o.hp);
std::swap(name, o.name);
std::swap(inventory, o.inventory);
std::swap(color, o.color);
std::swap(weapons, o.weapons);
std::swap(equipped, o.equipped);
std::swap(path, o.path);
return *this;
}
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::unique_ptr<MonsterT>(new MonsterT());
UnPackTo(_o.get(), _resolver);

View File

@@ -205,6 +205,7 @@ impl<'a> Default for MonsterArgs<'a> {
}
}
}
pub struct MonsterBuilder<'a: 'b, 'b> {
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,

View File

@@ -70,6 +70,7 @@ impl<'a> flatbuffers::Verifiable for Vec3 {
v.in_buffer::<Self>(pos)
}
}
impl<'a> Vec3 {
#[allow(clippy::too_many_arguments)]
pub fn new(

View File

@@ -89,6 +89,7 @@ impl<'a> Default for WeaponArgs<'a> {
}
}
}
pub struct WeaponBuilder<'a: 'b, 'b> {
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,

View File

@@ -34,6 +34,11 @@ parser.add_argument(
action="store_true",
help="skip generating tests involving monster_extra.fbs",
)
parser.add_argument(
"--skip-gen-reflection",
action="store_true",
help="skip generating the reflection.fbs files",
)
args = parser.parse_args()
# Get the path where this script is located so we can invoke the script from
@@ -74,7 +79,25 @@ def flatc(
cmd += [schema] if isinstance(schema, str) else schema
if data:
cmd += [data] if isinstance(data, str) else data
subprocess.run(cmd, cwd=cwd)
result = subprocess.run(cmd, cwd=str(cwd), check=True)
# Generate the code for flatbuffers reflection schema
def flatc_reflection(options, location, target):
full_options = ["--no-prefix"] + options
temp_dir = ".tmp"
flatc(
full_options,
prefix=temp_dir,
schema="reflection.fbs",
cwd=reflection_path,
)
new_reflection_path = Path(reflection_path, temp_dir, target)
original_reflection_path = Path(root_path, location, target)
if not filecmp.cmp(str(new_reflection_path), str(original_reflection_path)):
shutil.rmtree(str(original_reflection_path))
shutil.move(str(new_reflection_path), str(original_reflection_path))
shutil.rmtree(str(Path(reflection_path, temp_dir)))
# Glob a pattern relative to file path
@@ -102,7 +125,14 @@ CPP_17_OPTS = NO_INCL_OPTS + [
"--cpp-static-reflection",
"--gen-object-api",
]
RUST_OPTS = BASE_OPTS + ["--rust", "--gen-all", "--gen-name-strings"]
RUST_OPTS = BASE_OPTS + ["--rust", "--gen-all", "--gen-name-strings", "--rust-module-root-file"]
RUST_SERIALIZE_OPTS = BASE_OPTS + [
"--rust",
"--gen-all",
"--gen-name-strings",
"--rust-serialize",
"--rust-module-root-file",
]
TS_OPTS = ["--ts", "--gen-name-strings"]
LOBSTER_OPTS = ["--lobster"]
SWIFT_OPTS = ["--swift", "--gen-json-emit", "--bfbs-filenames", str(tests_path)]
@@ -137,7 +167,7 @@ flatc(
flatc(
["--lua", "--bfbs-filenames", str(tests_path)],
schema="monster_test.fbs",
include="include_test"
include="include_test",
)
flatc(
@@ -155,6 +185,14 @@ flatc(
data="monsterdata_test.json",
)
flatc(
RUST_SERIALIZE_OPTS,
schema="monster_test.fbs",
include="include_test",
prefix="monster_test_serialize",
data="monsterdata_test.json",
)
flatc(
options=BASE_OPTS + ["--python"],
schema="monster_test.fbs",
@@ -162,6 +200,13 @@ flatc(
data="monsterdata_test.json",
)
flatc(
options=BASE_OPTS + ["--python", "--gen-onefile"],
schema="monster_test.fbs",
include="include_test",
data="monsterdata_test.json",
)
# For Rust we currently generate two independent schemas, with namespace_test2
# duplicating the types in namespace_test1
flatc(
@@ -338,6 +383,11 @@ flatc(
schema="more_defaults.fbs",
prefix=swift_prefix,
)
flatc(
SWIFT_OPTS + BASE_OPTS,
schema="MutatingBool.fbs",
prefix=swift_prefix,
)
# --filename-suffix and --filename-ext tests
flatc(
@@ -353,7 +403,7 @@ assert (
new_monster_file.exists()
), "filename suffix option did not produce a file"
assert filecmp.cmp(
orig_monster_file, new_monster_file
str(orig_monster_file), str(new_monster_file)
), "filename suffix option did not produce identical results"
new_monster_file.unlink()
@@ -391,17 +441,13 @@ flatc(
)
# Reflection
temp_dir = ".tmp"
flatc(
["-c", "--cpp-std", "c++0x", "--no-prefix"],
prefix=temp_dir,
schema="reflection.fbs",
cwd=reflection_path,
)
new_reflection_file = Path(reflection_path, temp_dir, "reflection_generated.h")
original_reflection_file = Path(
root_path, "include/flatbuffers/reflection_generated.h"
)
if not filecmp.cmp(new_reflection_file, original_reflection_file):
shutil.move(new_reflection_file, original_reflection_file)
shutil.rmtree(Path(reflection_path, temp_dir))
# Skip generating the reflection if told too, as we run this script after
# building flatc which uses the reflection_generated.h itself.
if not args.skip_gen_reflection:
# C++ Reflection
flatc_reflection(["-c", "--cpp-std", "c++0x"], "include/flatbuffers",
"reflection_generated.h")
# Python Reflection
flatc_reflection(["-p"], "python/flatbuffers", "reflection")

View File

@@ -17,8 +17,8 @@
#include "flatbuffers/flatc.h"
#include <list>
#include <sstream>
#include "bfbs_gen_lua.h"
#include "flatbuffers/util.h"
namespace flatbuffers {
@@ -59,139 +59,271 @@ void FlatCompiler::Error(const std::string &err, bool usage,
params_.error_fn(this, err, usage, show_exe_name);
}
const static FlatCOption options[] = {
{ "o", "", "PATH", "Prefix PATH to all generated files." },
{ "I", "", "PATH", "Search for includes in the specified path." },
{ "M", "", "", "Print make rules for generated files." },
{ "", "version", "", "Print the version number of flatc and exit." },
{ "h", "help", "", "Prints this help text and exit." },
{ "", "string-json", "",
"Strict JSON: field names must be / will be quoted, no trailing commas in "
"tables/vectors." },
{ "", "allow-non-utf8", "",
"Pass non-UTF-8 input through parser and emit nonstandard \\x escapes in "
"JSON. (Default is to raise parse error on non-UTF-8 input.)" },
{ "", "natural-utf8", "",
"Output strings with UTF-8 as human-readable strings. By default, UTF-8 "
"characters are printed as \\uXXXX escapes." },
{ "", "defaults-json", "",
"Output fields whose value is the default when writing JSON" },
{ "", "unknown-json", "",
"Allow fields in JSON that are not defined in the schema. These fields "
"will be discared when generating binaries." },
{ "", "no-prefix", "",
"Don\'t prefix enum values with the enum type in C++." },
{ "", "scoped-enums", "",
"Use C++11 style scoped and strongly typed enums. Also implies "
"--no-prefix." },
{ "", "gen-inclues", "",
"(deprecated), this is the default behavior. If the original behavior is "
"required (no include statements) use --no-includes." },
{ "", "no-includes", "",
"Don\'t generate include statements for included schemas the generated "
"file depends on (C++ / Python)." },
{ "", "gen-mutable", "",
"Generate accessors that can mutate buffers in-place." },
{ "", "gen-onefile", "",
"Generate single output file for C#, Go, and Python." },
{ "", "gen-name-strings", "",
"Generate type name functions for C++ and Rust." },
{ "", "gen-object-api", "", "Generate an additional object-based API." },
{ "", "gen-compare", "", "Generate operator== for object-based API types." },
{ "", "gen-nullable", "",
"Add Clang _Nullable for C++ pointer. or @Nullable for Java" },
{ "", "java-checkerframe", "", "Add @Pure for Java." },
{ "", "gen-generated", "", "Add @Generated annotation for Java." },
{ "", "gen-jvmstatic", "",
"Add @JvmStatic annotation for Kotlin methods in companion object for "
"interop from Java to Kotlin." },
{ "", "gen-all", "",
"Generate not just code for the current schema files, but for all files it "
"includes as well. If the language uses a single file for output (by "
"default the case for C++ and JS), all code will end up in this one "
"file." },
{ "", "gen-json-emit", "",
"Generates encoding code which emits Flatbuffers into JSON" },
{ "", "cpp-include", "", "Adds an #include in generated file." },
{ "", "cpp-ptr-type", "T",
"Set object API pointer type (default std::unique_ptr)." },
{ "", "cpp-str-type", "T",
"Set object API string type (default std::string). T::c_str(), T::length() "
"and T::empty() must be supported. The custom type also needs to be "
"constructible from std::string (see the --cpp-str-flex-ctor option to "
"change this behavior)" },
{ "", "cpp-str-flex-ctor", "",
"Don't construct custom string types by passing std::string from "
"Flatbuffers, but (char* + length)." },
{ "", "cpp-field-case-style", "STYLE",
"Generate C++ fields using selected case style. Supported STYLE values: * "
"'unchanged' - leave unchanged (default) * 'upper' - schema snake_case "
"emits UpperCamel; * 'lower' - schema snake_case emits lowerCamel." },
{ "", "cpp-std", "CPP_STD",
"Generate a C++ code using features of selected C++ standard. Supported "
"CPP_STD values: * 'c++0x' - generate code compatible with old compilers; "
"'c++11' - use C++11 code generator (default); * 'c++17' - use C++17 "
"features in generated code (experimental)." },
{ "", "cpp-static-reflection", "",
"When using C++17, generate extra code to provide compile-time (static) "
"reflection of Flatbuffers types. Requires --cpp-std to be \"c++17\" or "
"higher." },
{ "", "object-prefix", "PREFIX",
"Customize class prefix for C++ object-based API." },
{ "", "object-suffix", "SUFFIX",
"Customize class suffix for C++ object-based API. Default Value is "
"\"T\"." },
{ "", "go-namespace", "", "Generate the overriding namespace in Golang." },
{ "", "go-import", "IMPORT",
"Generate the overriding import for flatbuffers in Golang (default is "
"\"github.com/google/flatbuffers/go\")." },
{ "", "raw-binary", "",
"Allow binaries without file_identifier to be read. This may crash flatc "
"given a mismatched schema." },
{ "", "size-prefixed", "", "Input binaries are size prefixed buffers." },
{ "", "proto", "", "Input is a .proto, translate to .fbs." },
{ "", "proto-namespace-suffix", "SUFFIX",
"Add this namespace to any flatbuffers generated from protobufs." },
{ "", "oneof-union", "", "Translate .proto oneofs to flatbuffer unions." },
{ "", "grpc", "", "Generate GRPC interfaces for the specified languages." },
{ "", "schema", "", "Serialize schemas instead of JSON (use with -b)." },
{ "", "bfbs-filenames", "PATH",
"Sets the root path where reflection filenames in reflection.fbs are "
"relative to. The 'root' is denoted with `//`. E.g. if PATH=/a/b/c "
"then /a/d/e.fbs will be serialized as //../d/e.fbs. (PATH defaults to the "
"directory of the first provided schema file." },
{ "", "bfbs-comments", "", "Add doc comments to the binary schema files." },
{ "", "bfbs-builtins", "",
"Add builtin attributes to the binary schema files." },
{ "", "bfbs-gen-embed", "",
"Generate code to embed the bfbs schema to the source." },
{ "", "conform", "FILE",
"Specify a schema the following schemas should be an evolution of. Gives "
"errors if not." },
{ "", "conform-includes", "PATH",
"Include path for the schema given with --conform PATH" },
{ "", "filename-suffix", "SUFFIX",
"The suffix appended to the generated file names (Default is "
"'_generated')." },
{ "", "filename-ext", "EXT",
"The extension appended to the generated file names. Default is "
"language-specific (e.g., '.h' for C++)" },
{ "", "include-prefix", "PATH",
"Prefix this PATH to any generated include statements." },
{ "", "keep-prefix", "",
"Keep original prefix of schema include statement." },
{ "", "reflect-types", "",
"Add minimal type reflection to code generation." },
{ "", "reflect-names", "", "Add minimal type/name reflection." },
{ "", "rust-serialize", "",
"Implement serde::Serialize on generated Rust types." },
{"", "rust-module-root-file", "",
"Generate rust code in individual files with a module root file."},
{ "", "root-type", "T", "Select or override the default root_type." },
{ "", "require-explicit-ids", "",
"When parsing schemas, require explicit ids (id: x)." },
{ "", "force-defaults", "",
"Emit default values in binary output from JSON" },
{ "", "force-empty", "",
"When serializing from object API representation, force strings and "
"vectors to empty rather than null." },
{ "", "force-empty-vectors", "",
"When serializing from object API representation, force vectors to empty "
"rather than null." },
{ "", "flexbuffers", "",
"Used with \"binary\" and \"json\" options, it generates data using "
"schema-less FlexBuffers." },
{ "", "no-warnings", "", "Inhibit all warnings messages." },
{ "", "warning-as-errors", "", "Treat all warnings as errors." },
{ "", "cs-global-alias", "",
"Prepend \"global::\" to all user generated csharp classes and "
"structs." },
{ "", "cs-gen-json-serializer", "",
"Allows (de)serialization of JSON text in the Object API. (requires "
"--gen-object-api)." },
{ "", "json-nested-bytes", "",
"Allow a nested_flatbuffer field to be parsed as a vector of bytes"
"in JSON, which is unsafe unless checked by a verifier afterwards." },
};
static void AppendTextWrappedString(std::stringstream &ss, std::string &text,
size_t max_col, size_t start_col) {
size_t max_line_length = max_col - start_col;
if (text.length() > max_line_length) {
size_t ideal_break_location = text.rfind(' ', max_line_length);
size_t length = std::min(max_line_length, ideal_break_location);
ss << text.substr(0, length) << "\n";
ss << std::string(start_col, ' ');
std::string rest_of_description = text.substr(
((ideal_break_location < max_line_length || text.at(length) == ' ')
? length + 1
: length));
AppendTextWrappedString(ss, rest_of_description, max_col, start_col);
} else {
ss << text;
}
}
static void AppendOption(std::stringstream &ss, const FlatCOption &option,
size_t max_col, size_t min_col_for_description) {
size_t chars = 2;
ss << " ";
if (!option.short_opt.empty()) {
chars += 2 + option.short_opt.length();
ss << "-" << option.short_opt;
if (!option.long_opt.empty()) {
chars++;
ss << ",";
}
ss << " ";
}
if (!option.long_opt.empty()) {
chars += 3 + option.long_opt.length();
ss << "--" << option.long_opt << " ";
}
if (!option.parameter.empty()) {
chars += 1 + option.parameter.length();
ss << option.parameter << " ";
}
size_t start_of_description = chars;
if (start_of_description > min_col_for_description) {
ss << "\n";
start_of_description = min_col_for_description;
ss << std::string(start_of_description, ' ');
} else {
while (start_of_description < min_col_for_description) {
ss << " ";
start_of_description++;
}
}
if (!option.description.empty()) {
std::string description = option.description;
AppendTextWrappedString(ss, description, max_col, start_of_description);
}
ss << "\n";
}
static void AppendShortOption(std::stringstream &ss,
const FlatCOption &option) {
if (!option.short_opt.empty()) {
ss << "-" << option.short_opt;
if (!option.long_opt.empty()) { ss << "|"; }
}
if (!option.long_opt.empty()) { ss << "--" << option.long_opt; }
}
std::string FlatCompiler::GetShortUsageString(const char *program_name) const {
std::stringstream ss;
ss << "Usage: " << program_name << " [";
for (size_t i = 0; i < params_.num_generators; ++i) {
const Generator &g = params_.generators[i];
AppendShortOption(ss, g.option);
ss << ", ";
}
for (const FlatCOption &option : options) {
AppendShortOption(ss, option);
ss << ", ";
}
ss.seekp(-2, ss.cur);
ss << "]... FILE... [-- FILE...]";
std::string help = ss.str();
std::stringstream ss_textwrap;
AppendTextWrappedString(ss_textwrap, help, 80, 0);
return ss_textwrap.str();
}
std::string FlatCompiler::GetUsageString(const char *program_name) const {
std::stringstream ss;
ss << "Usage: " << program_name << " [OPTION]... FILE... [-- FILE...]\n";
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";
AppendOption(ss, g.option, 80, 25);
}
// 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"
" --gen-json-emit Generates encoding code which emits Flatbuffers into JSON\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-field-case-style STYLE Generate C++ fields using selected case style.\n"
" Supported STYLE values:\n"
" * 'unchanged' - leave unchanged (default);\n"
" * 'upper' - schema snake_case emits UpperCamel;\n"
" * 'lower' - schema snake_case emits lowerCamel.\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-filenames PATH Sets the root path where reflection filenames in \n"
" reflection.fbs are relative to. The 'root' is denoted with \n"
" `//`. E.g. if PATH=/a/b/c \n then /a/d/e.fbs will be serialized\n"
" as //../d/e.fbs. (PATH defaults to the directory of the first\n"
" provided schema file.)\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"
" --cs-global-alias Prepend \"global::\" to all user generated csharp classes and structs.\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
ss << "\n";
for (const FlatCOption &option : options) {
AppendOption(ss, option, 80, 25);
}
ss << "\n";
std::string files_description =
"FILEs may be schemas (must end in .fbs), binary schemas (must end in "
".bfbs) or JSON files (conforming to preceding schema). FILEs after the "
"-- must be binary flatbuffer format files. Output files are named using "
"the base file name of the input, and written to the current directory "
"or the path given by -o. example: " +
std::string(program_name) + " -c -b schema1.fbs schema2.fbs data.json";
AppendTextWrappedString(ss, files_description, 80, 0);
ss << "\n";
return ss.str();
}
@@ -200,6 +332,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
return 0;
}
if (argc <= 1) { Error("Need to provide at least one argument."); }
flatbuffers::IDLOptions opts;
std::string output_path;
@@ -217,7 +351,9 @@ int FlatCompiler::Compile(int argc, const char **argv) {
size_t binary_files_from = std::numeric_limits<size_t>::max();
std::string conform_to_schema;
for (int argi = 0; argi < argc; argi++) {
const char *program_name = argv[0];
for (int argi = 1; argi < argc; argi++) {
std::string arg = argv[argi];
if (arg[0] == '-') {
if (filenames.size() && arg[1] != '-')
@@ -331,6 +467,7 @@ int FlatCompiler::Compile(int argc, const char **argv) {
opts.include_dependence_headers = false;
} else if (arg == "--gen-onefile") {
opts.one_file = true;
opts.include_dependence_headers = false;
} else if (arg == "--raw-binary") {
raw_binary = true;
} else if (arg == "--size-prefixed") {
@@ -351,6 +488,9 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} else if (arg == "--version") {
printf("flatc version %s\n", FLATC_VERSION());
exit(0);
} else if (arg == "--help" || arg == "-h") {
printf("%s\n", GetUsageString(program_name).c_str());
exit(0);
} else if (arg == "--grpc") {
grpc_enabled = true;
} else if (arg == "--bfbs-comments") {
@@ -363,6 +503,10 @@ int FlatCompiler::Compile(int argc, const char **argv) {
opts.mini_reflect = IDLOptions::kTypes;
} else if (arg == "--reflect-names") {
opts.mini_reflect = IDLOptions::kTypesAndNames;
} else if (arg == "--rust-serialize") {
opts.rust_serialize = true;
} else if (arg == "--rust-module-root-file") {
opts.rust_module_root_file = true;
} else if (arg == "--require-explicit-ids") {
opts.require_explicit_ids = true;
} else if (arg == "--root-type") {
@@ -391,6 +535,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
opts.gen_jvmstatic = true;
} else if (arg == "--no-warnings") {
opts.no_warnings = true;
} else if (arg == "--warnings-as-errors") {
opts.warnings_as_errors = true;
} else if (arg == "--cpp-std") {
if (++argi >= argc)
Error("missing C++ standard specification" + arg, true);
@@ -401,11 +547,12 @@ int FlatCompiler::Compile(int argc, const char **argv) {
opts.cpp_static_reflection = true;
} else if (arg == "--cs-global-alias") {
opts.cs_global_alias = true;
} else if (arg == "--json-nested-bytes") {
opts.json_nested_legacy_flatbuffers = 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)) {
if (arg == "--" + params_.generators[i].option.long_opt ||
arg == "-" + params_.generators[i].option.short_opt) {
generator_enabled[i] = true;
any_generator = true;
opts.lang_to_generate |= params_.generators[i].lang;
@@ -434,6 +581,12 @@ int FlatCompiler::Compile(int argc, const char **argv) {
Error("no options: specify at least one generator.", true);
}
if (opts.cs_gen_json_serializer && !opts.generate_object_based_api) {
Error(
"--cs-gen-json-serializer requires --gen-object-api to be set as "
"well.");
}
flatbuffers::Parser conform_parser;
if (!conform_to_schema.empty()) {
std::string contents;
@@ -509,9 +662,12 @@ int FlatCompiler::Compile(int argc, const char **argv) {
LoadBinarySchema(*parser.get(), filename, contents);
} else 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());
auto data = reinterpret_cast<const uint8_t *>(contents.c_str());
auto size = contents.size();
std::vector<uint8_t> reuse_tracker;
if (!flexbuffers::VerifyBuffer(data, size, &reuse_tracker))
Error("flexbuffers file failed to verify: " + filename, false);
parser->flex_root_ = flexbuffers::GetRoot(data, size);
} else {
parser->flex_builder_.Clear();
ParseFile(*parser.get(), filename, contents, include_directories);
@@ -614,9 +770,19 @@ int FlatCompiler::Compile(int argc, const char **argv) {
// in any files coming up next.
parser->MarkGenerated();
}
if (opts.lang_to_generate & IDLOptions::kRust && !parser->opts.one_file) {
GenerateRustModuleRootFile(*parser, output_path);
// Once all the files have been parsed, run any generators Parsing Completed
// function for final generation.
for (size_t i = 0; i < params_.num_generators; ++i) {
if (generator_enabled[i] &&
params_.generators[i].parsing_completed != nullptr) {
if (!params_.generators[i].parsing_completed(*parser, output_path)) {
Error("failed running parsing completed for " +
std::string(params_.generators[i].lang_name));
}
}
}
return 0;
}

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <cstdio>
#include <memory>
#include "bfbs_gen_lua.h"
@@ -27,16 +28,16 @@ static void Warn(const flatbuffers::FlatCompiler *flatc,
const std::string &warn, bool show_exe_name) {
(void)flatc;
if (show_exe_name) { printf("%s: ", g_program_name); }
fprintf(stderr, "warning: %s\n", warn.c_str());
fprintf(stderr, "\nwarning:\n %s\n\n", warn.c_str());
}
static void Error(const flatbuffers::FlatCompiler *flatc,
const std::string &err, bool usage, bool show_exe_name) {
if (show_exe_name) { printf("%s: ", g_program_name); }
fprintf(stderr, "error: %s\n", err.c_str());
if (usage && flatc) {
fprintf(stderr, "%s", flatc->GetUsageString(g_program_name).c_str());
fprintf(stderr, "%s\n", flatc->GetShortUsageString(g_program_name).c_str());
}
fprintf(stderr, "\nerror:\n %s\n\n", err.c_str());
exit(1);
}
@@ -62,61 +63,88 @@ int main(int argc, const char *argv[]) {
g_program_name = argv[0];
const flatbuffers::FlatCompiler::Generator generators[] = {
{ flatbuffers::GenerateBinary, "-b", "--binary", "binary", false, nullptr,
{ flatbuffers::GenerateBinary, "binary", false, nullptr,
flatbuffers::IDLOptions::kBinary,
"Generate wire format binaries for any data definitions",
flatbuffers::BinaryMakeRule, nullptr },
{ flatbuffers::GenerateTextFile, "-t", "--json", "text", false, nullptr,
flatbuffers::FlatCOption{
"b", "binary", "",
"Generate wire format binaries for any data definitions" },
flatbuffers::BinaryMakeRule, nullptr, nullptr },
{ flatbuffers::GenerateTextFile, "text", false, nullptr,
flatbuffers::IDLOptions::kJson,
"Generate text output for any data definitions",
flatbuffers::TextMakeRule, nullptr },
{ flatbuffers::GenerateCPP, "-c", "--cpp", "C++", true,
flatbuffers::GenerateCppGRPC, flatbuffers::IDLOptions::kCpp,
"Generate C++ headers for tables/structs", flatbuffers::CPPMakeRule,
nullptr },
{ flatbuffers::GenerateGo, "-g", "--go", "Go", true,
flatbuffers::GenerateGoGRPC, flatbuffers::IDLOptions::kGo,
"Generate Go files for tables/structs", nullptr, nullptr },
{ flatbuffers::GenerateJava, "-j", "--java", "Java", true,
flatbuffers::GenerateJavaGRPC, flatbuffers::IDLOptions::kJava,
"Generate Java classes for tables/structs", flatbuffers::JavaMakeRule,
nullptr },
{ flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr,
flatbuffers::FlatCOption{
"t", "json", "", "Generate text output for any data definitions" },
flatbuffers::TextMakeRule, nullptr, nullptr },
{ flatbuffers::GenerateCPP, "C++", true, flatbuffers::GenerateCppGRPC,
flatbuffers::IDLOptions::kCpp,
flatbuffers::FlatCOption{ "c", "cpp", "",
"Generate C++ headers for tables/structs" },
flatbuffers::CPPMakeRule, nullptr, nullptr },
{ flatbuffers::GenerateGo, "Go", true, flatbuffers::GenerateGoGRPC,
flatbuffers::IDLOptions::kGo,
flatbuffers::FlatCOption{ "g", "go", "",
"Generate Go files for tables/structs" },
nullptr, nullptr, nullptr },
{ flatbuffers::GenerateJava, "Java", true, flatbuffers::GenerateJavaGRPC,
flatbuffers::IDLOptions::kJava,
flatbuffers::FlatCOption{ "j", "java", "",
"Generate Java classes for tables/structs" },
flatbuffers::JavaMakeRule, nullptr, nullptr },
{ flatbuffers::GenerateDart, "Dart", true, nullptr,
flatbuffers::IDLOptions::kDart,
"Generate Dart classes for tables/structs", flatbuffers::DartMakeRule,
nullptr },
{ flatbuffers::GenerateTS, "-T", "--ts", "TypeScript", true,
flatbuffers::GenerateTSGRPC, flatbuffers::IDLOptions::kTs,
"Generate TypeScript code for tables/structs", flatbuffers::TSMakeRule,
nullptr },
{ flatbuffers::GenerateCSharp, "-n", "--csharp", "C#", true, nullptr,
flatbuffers::FlatCOption{ "d", "dart", "",
"Generate Dart classes for tables/structs" },
flatbuffers::DartMakeRule, nullptr, nullptr },
{ flatbuffers::GenerateTS, "TypeScript", true, flatbuffers::GenerateTSGRPC,
flatbuffers::IDLOptions::kTs,
flatbuffers::FlatCOption{ "T", "ts", "",
"Generate TypeScript code for tables/structs" },
flatbuffers::TSMakeRule, nullptr, nullptr },
{ flatbuffers::GenerateCSharp, "C#", true, nullptr,
flatbuffers::IDLOptions::kCSharp,
"Generate C# classes for tables/structs", flatbuffers::CSharpMakeRule,
nullptr },
{ flatbuffers::GeneratePython, "-p", "--python", "Python", true,
flatbuffers::FlatCOption{ "n", "csharp", "",
"Generate C# classes for tables/structs" },
flatbuffers::CSharpMakeRule, nullptr, nullptr },
{ flatbuffers::GeneratePython, "Python", true,
flatbuffers::GeneratePythonGRPC, flatbuffers::IDLOptions::kPython,
"Generate Python files for tables/structs", nullptr, nullptr },
{ flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true,
nullptr, flatbuffers::IDLOptions::kLobster,
"Generate Lobster files for tables/structs", nullptr, nullptr },
{ flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr,
flatbuffers::IDLOptions::kLua, "Generate Lua files for tables/structs",
nullptr, bfbs_gen_lua.get() },
{ flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr,
flatbuffers::IDLOptions::kRust, "Generate Rust files for tables/structs",
flatbuffers::RustMakeRule, nullptr },
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr,
flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs",
nullptr, nullptr },
{ flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr,
flatbuffers::FlatCOption{ "p", "python", "",
"Generate Python files for tables/structs" },
nullptr, nullptr, nullptr },
{ flatbuffers::GenerateLobster, "Lobster", true, nullptr,
flatbuffers::IDLOptions::kLobster,
flatbuffers::FlatCOption{ "", "lobster", "",
"Generate Lobster files for tables/structs" },
nullptr, nullptr, nullptr },
{ flatbuffers::GenerateLua, "Lua", true, nullptr,
flatbuffers::IDLOptions::kLua,
flatbuffers::FlatCOption{ "l", "lua", "",
"Generate Lua files for tables/structs" },
nullptr, bfbs_gen_lua.get(), nullptr },
{ flatbuffers::GenerateRust, "Rust", true, nullptr,
flatbuffers::IDLOptions::kRust,
flatbuffers::FlatCOption{ "r", "rust", "",
"Generate Rust files for tables/structs" },
flatbuffers::RustMakeRule, nullptr,
flatbuffers::GenerateRustModuleRootFile },
{ flatbuffers::GeneratePhp, "PHP", true, nullptr,
flatbuffers::IDLOptions::kPhp,
flatbuffers::FlatCOption{ "", "php", "",
"Generate PHP files for tables/structs" },
nullptr, nullptr, nullptr },
{ flatbuffers::GenerateKotlin, "Kotlin", true, nullptr,
flatbuffers::IDLOptions::kKotlin,
"Generate Kotlin classes for tables/structs", nullptr, nullptr },
{ flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema",
true, nullptr, flatbuffers::IDLOptions::kJsonSchema,
"Generate Json schema", nullptr, nullptr },
{ flatbuffers::GenerateSwift, nullptr, "--swift", "swift", true,
flatbuffers::GenerateSwiftGRPC, flatbuffers::IDLOptions::kSwift,
"Generate Swift files for tables/structs", nullptr, nullptr },
flatbuffers::FlatCOption{ "", "kotlin", "",
"Generate Kotlin classes for tables/structs" },
nullptr, nullptr, nullptr },
{ flatbuffers::GenerateJsonSchema, "JsonSchema", true, nullptr,
flatbuffers::IDLOptions::kJsonSchema,
flatbuffers::FlatCOption{ "", "jsonschema", "", "Generate Json schema" },
nullptr, nullptr, nullptr },
{ flatbuffers::GenerateSwift, "swift", true, flatbuffers::GenerateSwiftGRPC,
flatbuffers::IDLOptions::kSwift,
flatbuffers::FlatCOption{ "", "swift", "",
"Generate Swift files for tables/structs" },
nullptr, nullptr, nullptr },
};
flatbuffers::FlatCompiler::InitParams params;
@@ -126,5 +154,5 @@ int main(int argc, const char *argv[]) {
params.error_fn = Error;
flatbuffers::FlatCompiler flatc(params);
return flatc.Compile(argc - 1, argv + 1);
return flatc.Compile(argc, argv);
}

View File

@@ -283,6 +283,9 @@ class CppGenerator : public BaseGenerator {
code_ += "#pragma clang system_header\n\n";
}
code_ += "#include \"flatbuffers/flatbuffers.h\"";
code_ += "";
SetNameSpace(struct_def.defined_namespace);
auto name = Name(struct_def);
code_.SetValue("STRUCT_NAME", name);
@@ -532,6 +535,16 @@ class CppGenerator : public BaseGenerator {
code_ += " buf, {{STRUCT_NAME}}Identifier());";
code_ += "}";
code_ += "";
// Check if a size-prefixed buffer has the identifier.
code_ += "inline \\";
code_ +=
"bool SizePrefixed{{STRUCT_NAME}}BufferHasIdentifier(const void "
"*buf) {";
code_ += " return flatbuffers::BufferHasIdentifier(";
code_ += " buf, {{STRUCT_NAME}}Identifier(), true);";
code_ += "}";
code_ += "";
}
// The root verifier.
@@ -658,8 +671,9 @@ class CppGenerator : public BaseGenerator {
}
bool VectorElementUserFacing(const Type &type) const {
return opts_.g_cpp_std >= cpp::CPP_STD_17 && opts_.g_only_fixed_enums &&
IsEnum(type);
return (opts_.scoped_enums && IsEnum(type)) ||
(opts_.g_cpp_std >= cpp::CPP_STD_17 && opts_.g_only_fixed_enums &&
IsEnum(type));
}
void GenComment(const std::vector<std::string> &dc, const char *prefix = "") {
@@ -799,7 +813,7 @@ class CppGenerator : public BaseGenerator {
}
std::string GenTypeNative(const Type &type, bool invector,
const FieldDef &field) {
const FieldDef &field, bool forcopy = false) {
switch (type.base_type) {
case BASE_TYPE_STRING: {
return NativeString(&field);
@@ -820,15 +834,14 @@ class CppGenerator : public BaseGenerator {
if (IsStruct(type)) {
auto native_type = type.struct_def->attributes.Lookup("native_type");
if (native_type) { type_name = native_type->constant; }
if (invector || field.native_inline) {
if (invector || field.native_inline || forcopy) {
return type_name;
} else {
return GenTypeNativePtr(type_name, &field, false);
}
} else {
return GenTypeNativePtr(
WrapNativeNameInNameSpace(*type.struct_def, opts_), &field,
false);
const auto nn = WrapNativeNameInNameSpace(*type.struct_def, opts_);
return forcopy ? nn : GenTypeNativePtr(nn, &field, false);
}
}
case BASE_TYPE_UNION: {
@@ -1471,9 +1484,11 @@ class CppGenerator : public BaseGenerator {
" auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);";
if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
if (ev.union_type.struct_def->fixed) {
code_.SetValue("ALIGN",
NumToString(ev.union_type.struct_def->minalign));
code_ +=
" return verifier.Verify<{{TYPE}}>(static_cast<const "
"uint8_t *>(obj), 0);";
" return verifier.VerifyField<{{TYPE}}>("
"static_cast<const uint8_t *>(obj), 0, {{ALIGN}});";
} else {
code_ += getptr;
code_ += " return verifier.VerifyTable(ptr);";
@@ -1588,7 +1603,8 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("TYPE", GetUnionElement(ev, true, opts_));
code_ += " case {{LABEL}}: {";
bool copyable = true;
if (ev.union_type.base_type == BASE_TYPE_STRUCT &&
if (opts_.g_cpp_std < cpp::CPP_STD_11 &&
ev.union_type.base_type == BASE_TYPE_STRUCT &&
!ev.union_type.struct_def->fixed) {
// Don't generate code to copy if table is not copyable.
// TODO(wvo): make tables copyable instead.
@@ -1791,13 +1807,50 @@ class CppGenerator : public BaseGenerator {
}
}
// Returns true if `struct_def` needs a copy constructor and assignment
// operator because it has one or more table members, struct members with a
// custom cpp_type and non-naked pointer type, or vector members of those.
bool NeedsCopyCtorAssignOp(const StructDef &struct_def) {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
const auto &type = field.value.type;
if (field.deprecated) continue;
if (type.base_type == BASE_TYPE_STRUCT) {
const auto cpp_type = field.attributes.Lookup("cpp_type");
const auto cpp_ptr_type = field.attributes.Lookup("cpp_ptr_type");
const bool is_ptr = !(IsStruct(type) && field.native_inline) ||
(cpp_type && cpp_ptr_type->constant != "naked");
if (is_ptr) { return true; }
} else if (IsVector(type)) {
const auto vec_type = type.VectorType();
if (vec_type.base_type == BASE_TYPE_UTYPE) continue;
const auto cpp_type = field.attributes.Lookup("cpp_type");
const auto cpp_ptr_type = field.attributes.Lookup("cpp_ptr_type");
const bool is_ptr =
(vec_type.base_type == BASE_TYPE_STRUCT && !IsStruct(vec_type)) ||
(cpp_type && cpp_ptr_type->constant != "naked");
if (is_ptr) { return true; }
}
}
return false;
}
// Generate the default constructor for this struct. Properly initialize all
// scalar members with default values.
void GenDefaultConstructor(const StructDef &struct_def) {
code_.SetValue("NATIVE_NAME",
NativeName(Name(struct_def), &struct_def, opts_));
// In >= C++11, default member initializers are generated.
if (opts_.g_cpp_std >= cpp::CPP_STD_11) { return; }
// In >= C++11, default member initializers are generated. To allow for
// aggregate initialization, do not emit a default constructor at all, with
// the exception of types that need a copy/move ctors and assignment
// operators.
if (opts_.g_cpp_std >= cpp::CPP_STD_11) {
if (NeedsCopyCtorAssignOp(struct_def)) {
code_ += " {{NATIVE_NAME}}() = default;";
}
return;
}
std::string initializer_list;
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
@@ -1841,6 +1894,125 @@ class CppGenerator : public BaseGenerator {
code_ += " }";
}
// Generate the >= C++11 copy/move constructor and assignment operator
// declarations if required. Tables that are default-copyable do not get
// user-provided copy/move constructors and assignment operators so they
// remain aggregates.
void GenCopyMoveCtorAndAssigOpDecls(const StructDef &struct_def) {
if (opts_.g_cpp_std < cpp::CPP_STD_11) return;
if (!NeedsCopyCtorAssignOp(struct_def)) return;
code_.SetValue("NATIVE_NAME",
NativeName(Name(struct_def), &struct_def, opts_));
code_ += " {{NATIVE_NAME}}(const {{NATIVE_NAME}} &o);";
code_ +=
" {{NATIVE_NAME}}({{NATIVE_NAME}}&&) FLATBUFFERS_NOEXCEPT = "
"default;";
code_ +=
" {{NATIVE_NAME}} &operator=({{NATIVE_NAME}} o) FLATBUFFERS_NOEXCEPT;";
}
// Generate the >= C++11 copy constructor and assignment operator definitions.
void GenCopyCtorAssignOpDefs(const StructDef &struct_def) {
if (opts_.g_cpp_std < cpp::CPP_STD_11) return;
if (!NeedsCopyCtorAssignOp(struct_def)) return;
std::string initializer_list;
std::string vector_copies;
std::string swaps;
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
const auto &type = field.value.type;
if (field.deprecated || type.base_type == BASE_TYPE_UTYPE) continue;
if (type.base_type == BASE_TYPE_STRUCT) {
if (!initializer_list.empty()) { initializer_list += ",\n "; }
const auto cpp_type = field.attributes.Lookup("cpp_type");
const auto cpp_ptr_type = field.attributes.Lookup("cpp_ptr_type");
auto type_name = (cpp_type) ? cpp_type->constant
: GenTypeNative(type, /*invector*/ false,
field, /*forcopy*/ true);
const bool is_ptr = !(IsStruct(type) && field.native_inline) ||
(cpp_type && cpp_ptr_type->constant != "naked");
CodeWriter cw;
cw.SetValue("FIELD", Name(field));
cw.SetValue("TYPE", type_name);
if (is_ptr) {
cw +=
"{{FIELD}}((o.{{FIELD}}) ? new {{TYPE}}(*o.{{FIELD}}) : "
"nullptr)\\";
initializer_list += cw.ToString();
} else {
cw += "{{FIELD}}(o.{{FIELD}})\\";
initializer_list += cw.ToString();
}
} else if (IsVector(type)) {
const auto vec_type = type.VectorType();
if (vec_type.base_type == BASE_TYPE_UTYPE) continue;
const auto cpp_type = field.attributes.Lookup("cpp_type");
const auto cpp_ptr_type = field.attributes.Lookup("cpp_ptr_type");
const auto type_name = (cpp_type)
? cpp_type->constant
: GenTypeNative(vec_type, /*invector*/ true,
field, /*forcopy*/ true);
const bool is_ptr =
(vec_type.base_type == BASE_TYPE_STRUCT && !IsStruct(vec_type)) ||
(cpp_type && cpp_ptr_type->constant != "naked");
CodeWriter cw(" ");
cw.SetValue("FIELD", Name(field));
cw.SetValue("TYPE", type_name);
if (is_ptr) {
// Use emplace_back to construct the potentially-smart pointer element
// from a raw pointer to a new-allocated copy.
cw.IncrementIdentLevel();
cw += "{{FIELD}}.reserve(o.{{FIELD}}.size());";
cw +=
"for (const auto &v : o.{{FIELD}}) { "
"{{FIELD}}.emplace_back((v) ? new {{TYPE}}(*v) : nullptr); }";
vector_copies += cw.ToString();
} else {
// For non-pointer elements, use std::vector's copy constructor in the
// initializer list. This will yield better performance than an insert
// range loop for trivially-copyable element types.
if (!initializer_list.empty()) { initializer_list += ",\n "; }
cw += "{{FIELD}}(o.{{FIELD}})\\";
initializer_list += cw.ToString();
}
} else {
if (!initializer_list.empty()) { initializer_list += ",\n "; }
CodeWriter cw;
cw.SetValue("FIELD", Name(field));
cw += "{{FIELD}}(o.{{FIELD}})\\";
initializer_list += cw.ToString();
}
{
if (!swaps.empty()) { swaps += "\n "; }
CodeWriter cw;
cw.SetValue("FIELD", Name(field));
cw += "std::swap({{FIELD}}, o.{{FIELD}});\\";
swaps += cw.ToString();
}
}
if (!initializer_list.empty()) {
initializer_list = "\n : " + initializer_list;
}
if (!swaps.empty()) { swaps = " " + swaps; }
code_.SetValue("NATIVE_NAME",
NativeName(Name(struct_def), &struct_def, opts_));
code_.SetValue("INIT_LIST", initializer_list);
code_.SetValue("VEC_COPY", vector_copies);
code_.SetValue("SWAPS", swaps);
code_ +=
"inline {{NATIVE_NAME}}::{{NATIVE_NAME}}(const {{NATIVE_NAME}} &o)"
"{{INIT_LIST}} {";
code_ += "{{VEC_COPY}}}\n";
code_ +=
"inline {{NATIVE_NAME}} &{{NATIVE_NAME}}::operator="
"({{NATIVE_NAME}} o) FLATBUFFERS_NOEXCEPT {";
code_ += "{{SWAPS}}";
code_ += " return *this;\n}\n";
}
void GenCompareOperator(const StructDef &struct_def,
std::string accessSuffix = "") {
std::string compare_op;
@@ -1853,7 +2025,7 @@ class CppGenerator : public BaseGenerator {
field.value.type.element != BASE_TYPE_UTYPE)) {
if (!compare_op.empty()) { compare_op += " &&\n "; }
auto accessor = Name(field) + accessSuffix;
if (struct_def.fixed ||
if (struct_def.fixed || field.native_inline ||
field.value.type.base_type != BASE_TYPE_STRUCT) {
compare_op += "(lhs." + accessor + " == rhs." + accessor + ")";
} else {
@@ -1929,6 +2101,7 @@ class CppGenerator : public BaseGenerator {
}
GenOperatorNewDelete(struct_def);
GenDefaultConstructor(struct_def);
GenCopyMoveCtorAndAssigOpDecls(struct_def);
code_ += "};";
code_ += "";
}
@@ -1951,8 +2124,10 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("SIZE", GenTypeSize(field.value.type));
code_.SetValue("OFFSET", GenFieldOffsetName(field));
if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type)) {
code_.SetValue("ALIGN", NumToString(InlineAlignment(field.value.type)));
code_ +=
"{{PRE}}VerifyField{{REQUIRED}}<{{SIZE}}>(verifier, {{OFFSET}})\\";
"{{PRE}}VerifyField{{REQUIRED}}<{{SIZE}}>(verifier, "
"{{OFFSET}}, {{ALIGN}})\\";
} else {
code_ += "{{PRE}}VerifyOffset{{REQUIRED}}(verifier, {{OFFSET}})\\";
}
@@ -2004,8 +2179,13 @@ class CppGenerator : public BaseGenerator {
if (!nfn.empty()) {
code_.SetValue("CPP_NAME", nfn);
// FIXME: file_identifier.
code_ += "{{PRE}}verifier.VerifyNestedFlatBuffer<{{CPP_NAME}}>"
"({{NAME}}(), nullptr)\\";
code_ +=
"{{PRE}}verifier.VerifyNestedFlatBuffer<{{CPP_NAME}}>"
"({{NAME}}(), nullptr)\\";
} else if (field.flexbuffer) {
code_ +=
"{{PRE}}flexbuffers::VerifyNestedFlexBuffer"
"({{NAME}}(), verifier)\\";
}
break;
}
@@ -2030,8 +2210,8 @@ class CppGenerator : public BaseGenerator {
code_ += " }";
if (is_string) {
code_ += " int KeyCompareWithValue(const char *val) const {";
code_ += " return strcmp({{FIELD_NAME}}()->c_str(), val);";
code_ += " int KeyCompareWithValue(const char *_{{FIELD_NAME}}) const {";
code_ += " return strcmp({{FIELD_NAME}}()->c_str(), _{{FIELD_NAME}});";
code_ += " }";
} else {
FLATBUFFERS_ASSERT(IsScalar(field.value.type.base_type));
@@ -2042,10 +2222,11 @@ class CppGenerator : public BaseGenerator {
}
// 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);";
" int KeyCompareWithValue({{KEY_TYPE}} _{{FIELD_NAME}}) const {";
code_ +=
" return static_cast<int>({{FIELD_NAME}}() > _{{FIELD_NAME}}) - "
"static_cast<int>({{FIELD_NAME}}() < _{{FIELD_NAME}});";
code_ += " }";
}
}
@@ -3103,6 +3284,9 @@ class CppGenerator : public BaseGenerator {
NativeName(Name(struct_def), &struct_def, opts_));
if (opts_.generate_object_based_api) {
// Generate the >= C++11 copy ctor and assignment operator definitions.
GenCopyCtorAssignOpDefs(struct_def);
// Generate the X::UnPack() method.
code_ +=
"inline " + TableUnPackSignature(struct_def, false, opts_) + " {";

View File

@@ -246,9 +246,7 @@ class FlatBufFile : public grpc_generator::File {
return parser_.opts.filename_suffix + ".h";
}
std::string service_header_ext() const {
return parser_.opts.filename_suffix + ".grpc.fb.h";
}
std::string service_header_ext() const { return ".grpc.fb.h"; }
std::string package() const {
return parser_.current_namespace_->GetFullyQualifiedName("");
@@ -374,14 +372,10 @@ bool GenerateCppGRPC(const Parser &parser, const std::string &path,
grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) +
grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters);
return flatbuffers::SaveFile(
(path + file_name + parser.opts.filename_suffix + ".grpc.fb.h")
.c_str(),
header_code, false) &&
flatbuffers::SaveFile(
(path + file_name + parser.opts.filename_suffix + ".grpc.fb.cc")
.c_str(),
source_code, false);
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 {

View File

@@ -259,7 +259,6 @@ class KotlinGenerator : public BaseGenerator {
GenerateComment(enum_def.doc_comment, writer, &comment_config);
writer += "@Suppress(\"unused\")";
writer += "@ExperimentalUnsignedTypes";
writer += "class " + Esc(enum_def.name) + " private constructor() {";
writer.IncrementIdentLevel();
@@ -461,7 +460,6 @@ class KotlinGenerator : public BaseGenerator {
writer.SetValue("superclass", fixed ? "Struct" : "Table");
writer += "@Suppress(\"unused\")";
writer += "@ExperimentalUnsignedTypes";
writer += "class {{struct_name}} : {{superclass}}() {\n";
writer.IncrementIdentLevel();

View File

@@ -113,12 +113,6 @@ class PythonGenerator : public BaseGenerator {
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) {
@@ -562,10 +556,12 @@ class PythonGenerator : public BaseGenerator {
code += NumToString(struct_def.fields.vec.size());
code += ")\n";
// Generate method without struct name.
code += "def Start(builder):\n";
code +=
Indent + "return " + NormalizedName(struct_def) + "Start(builder)\n";
if (!parser_.opts.one_file) {
// Generate method without struct name.
code += "def Start(builder):\n";
code +=
Indent + "return " + NormalizedName(struct_def) + "Start(builder)\n";
}
}
// Set the value of a table's field.
@@ -595,16 +591,18 @@ class PythonGenerator : public BaseGenerator {
: field.value.constant;
code += ")\n";
// Generate method without struct name.
code += "def Add" + MakeCamel(NormalizedName(field));
code += "(builder, ";
code += MakeCamel(NormalizedName(field), false);
code += "):\n";
code += Indent + "return " + NormalizedName(struct_def) + "Add" +
MakeCamel(NormalizedName(field));
code += "(builder, ";
code += MakeCamel(NormalizedName(field), false);
code += ")\n";
if (!parser_.opts.one_file) {
// Generate method without struct name.
code += "def Add" + MakeCamel(NormalizedName(field));
code += "(builder, ";
code += MakeCamel(NormalizedName(field), false);
code += "):\n";
code += Indent + "return " + NormalizedName(struct_def) + "Add" +
MakeCamel(NormalizedName(field));
code += "(builder, ";
code += MakeCamel(NormalizedName(field), false);
code += ")\n";
}
}
// Set the value of one of the members of a table's vector.
@@ -623,13 +621,15 @@ class PythonGenerator : public BaseGenerator {
code += ", numElems, " + NumToString(alignment);
code += ")\n";
// Generate method without struct name.
code += "def Start";
code += MakeCamel(NormalizedName(field));
code += "Vector(builder, numElems):\n";
code += Indent + "return " + NormalizedName(struct_def) + "Start";
code += MakeCamel(NormalizedName(field));
code += "Vector(builder, numElems)\n";
if (!parser_.opts.one_file) {
// Generate method without struct name.
code += "def Start";
code += MakeCamel(NormalizedName(field));
code += "Vector(builder, numElems):\n";
code += Indent + "return " + NormalizedName(struct_def) + "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
@@ -670,12 +670,14 @@ class PythonGenerator : public BaseGenerator {
code += " = bytes\n";
code += Indent + "return builder.EndVector()\n";
// Generate method without struct and field name.
code += "def Make" + MakeCamel(NormalizedName(field)) +
"VectorFromBytes(builder, bytes):\n";
code += Indent + "return " + NormalizedName(struct_def) + "Make" +
MakeCamel(NormalizedName(field)) +
"VectorFromBytes(builder, bytes)\n";
if (!parser_.opts.one_file) {
// Generate method without struct and field name.
code += "def Make" + MakeCamel(NormalizedName(field)) +
"VectorFromBytes(builder, bytes):\n";
code += Indent + "return " + NormalizedName(struct_def) + "Make" +
MakeCamel(NormalizedName(field)) +
"VectorFromBytes(builder, bytes)\n";
}
}
// Get the offset of the end of a table.
@@ -687,9 +689,11 @@ class PythonGenerator : public BaseGenerator {
code += "(builder): ";
code += "return builder.EndObject()\n";
// Generate method without struct name.
code += "def End(builder):\n";
code += Indent + "return " + NormalizedName(struct_def) + "End(builder)";
if (!parser_.opts.one_file) {
// Generate method without struct name.
code += "def End(builder):\n";
code += Indent + "return " + NormalizedName(struct_def) + "End(builder)";
}
}
// Generate the receiver for function signatures.
@@ -1639,7 +1643,6 @@ class PythonGenerator : public BaseGenerator {
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.
@@ -1709,13 +1712,20 @@ class PythonGenerator : public BaseGenerator {
}
bool generate() {
if (!generateEnums()) return false;
if (!generateStructs()) return false;
std::string one_file_code;
if (!generateEnums(&one_file_code)) return false;
if (!generateStructs(&one_file_code)) return false;
if (parser_.opts.one_file) {
return SaveType(file_name_ + "_generated", *parser_.current_namespace_,
one_file_code, true);
}
return true;
}
private:
bool generateEnums() {
bool generateEnums(std::string *one_file_code) {
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) {
auto &enum_def = **it;
@@ -1724,12 +1734,19 @@ class PythonGenerator : public BaseGenerator {
if (parser_.opts.generate_object_based_api & enum_def.is_union) {
GenUnionCreator(enum_def, &enumcode);
}
if (!SaveType(enum_def, enumcode, false)) return false;
if (parser_.opts.one_file && !enumcode.empty()) {
*one_file_code += enumcode + "\n\n";
} else {
if (!SaveType(enum_def.name, *enum_def.defined_namespace, enumcode,
false))
return false;
}
}
return true;
}
bool generateStructs() {
bool generateStructs(std::string *one_file_code) {
for (auto it = parser_.structs_.vec.begin();
it != parser_.structs_.vec.end(); ++it) {
auto &struct_def = **it;
@@ -1738,7 +1755,14 @@ class PythonGenerator : public BaseGenerator {
if (parser_.opts.generate_object_based_api) {
GenStructForObjectAPI(struct_def, &declcode);
}
if (!SaveType(struct_def, declcode, true)) return false;
if (parser_.opts.one_file && !declcode.empty()) {
*one_file_code += declcode + "\n\n";
} else {
if (!SaveType(struct_def.name, *struct_def.defined_namespace, declcode,
true))
return false;
}
}
return true;
}
@@ -1757,12 +1781,12 @@ class PythonGenerator : public BaseGenerator {
}
// Save out the generated code for a Python Table type.
bool SaveType(const Definition &def, const std::string &classcode,
bool needs_imports) {
bool SaveType(const std::string &defname, const Namespace &ns,
const std::string &classcode, bool needs_imports) {
if (!classcode.length()) return true;
std::string namespace_dir = path_;
auto &namespaces = def.defined_namespace->components;
auto &namespaces = ns.components;
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
if (it != namespaces.begin()) namespace_dir += kPathSeparator;
namespace_dir += *it;
@@ -1771,10 +1795,9 @@ class PythonGenerator : public BaseGenerator {
}
std::string code = "";
BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code);
BeginFile(LastNamespacePart(ns), needs_imports, &code);
code += classcode;
std::string filename =
NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py";
std::string filename = NamespaceDir(ns) + defname + ".py";
return SaveFile(filename.c_str(), code, false);
}

View File

@@ -194,6 +194,11 @@ bool IsOptionalToBuilder(const FieldDef &field) {
bool GenerateRustModuleRootFile(const Parser &parser,
const std::string &output_dir) {
if (!parser.opts.rust_module_root_file) {
// Don't generate a root file when generating one file. This isn't an error
// so return true.
return true;
}
// We gather the symbols into a tree of namespaces (which are rust mods) and
// generate a file that gathers them all.
struct Module {
@@ -366,7 +371,7 @@ class RustGenerator : public BaseGenerator {
}
bool generate() {
if (parser_.opts.one_file) {
if (!parser_.opts.rust_module_root_file) {
return GenerateOneFile();
} else {
return GenerateIndividualFiles();
@@ -384,6 +389,11 @@ class RustGenerator : public BaseGenerator {
code_ += "extern crate flatbuffers;";
code_ += "use std::mem;";
code_ += "use std::cmp::Ordering;";
if (parser_.opts.rust_serialize) {
code_ += "extern crate serde;";
code_ +=
"use self::serde::ser::{Serialize, Serializer, SerializeStruct};";
}
code_ += "use self::flatbuffers::{EndianScalar, Follow};";
code_ += "use super::*;";
cur_name_space_ = symbol.defined_namespace;
@@ -842,6 +852,27 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("INTO_BASE", "self.0");
}
// Implement serde::Serialize
if (parser_.opts.rust_serialize) {
code_ += "impl Serialize for {{ENUM_NAME}} {";
code_ +=
" fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>";
code_ += " where";
code_ += " S: Serializer,";
code_ += " {";
if (IsBitFlagsEnum(enum_def)) {
code_ += " serializer.serialize_u32(self.bits() as u32)";
} else {
code_ +=
" serializer.serialize_unit_variant(\"{{ENUM_NAME}}\", self.0 "
"as "
"u32, self.variant_name().unwrap())";
}
code_ += " }";
code_ += "}";
code_ += "";
}
// Generate Follow and Push so we can serialize and stuff.
code_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_NAME}} {";
code_ += " type Inner = Self;";
@@ -2005,6 +2036,74 @@ class RustGenerator : public BaseGenerator {
code_ += " }";
code_ += " }";
code_ += "}";
code_ += "";
// Implement serde::Serialize
if (parser_.opts.rust_serialize) {
const auto numFields = struct_def.fields.vec.size();
code_.SetValue("NUM_FIELDS", NumToString(numFields));
code_ += "impl Serialize for {{STRUCT_NAME}}<'_> {";
code_ +=
" fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>";
code_ += " where";
code_ += " S: Serializer,";
code_ += " {";
if (numFields == 0) {
code_ +=
" let s = serializer.serialize_struct(\"{{STRUCT_NAME}}\", 0)?;";
} else {
code_ +=
" let mut s = serializer.serialize_struct(\"{{STRUCT_NAME}}\", "
"{{NUM_FIELDS}})?;";
}
ForAllTableFields(struct_def, [&](const FieldDef &field) {
const Type &type = field.value.type;
if (IsUnion(type)) {
if (type.base_type == BASE_TYPE_UNION) {
const auto &enum_def = *type.enum_def;
code_.SetValue("ENUM_NAME", WrapInNameSpace(enum_def));
code_.SetValue("FIELD_TYPE_FIELD_NAME", field.name);
code_ += " match self.{{FIELD_TYPE_FIELD_NAME}}_type() {";
code_ += " {{ENUM_NAME}}::NONE => (),";
ForAllUnionObjectVariantsBesidesNone(enum_def, [&] {
code_.SetValue("FIELD_TYPE_FIELD_NAME", field.name);
code_ += " {{ENUM_NAME}}::{{VARIANT_NAME}} => {";
code_ +=
" let f = "
"self.{{FIELD_TYPE_FIELD_NAME}}_as_{{U_ELEMENT_NAME}}()";
code_ +=
" .expect(\"Invalid union table, expected "
"`{{ENUM_NAME}}::{{VARIANT_NAME}}`.\");";
code_ += " s.serialize_field(\"{{FIELD_NAME}}\", &f)?;";
code_ += " }";
});
code_ += " _ => unimplemented!(),";
code_ += " }";
} else {
code_ +=
" s.serialize_field(\"{{FIELD_NAME}}\", "
"&self.{{FIELD_NAME}}())?;";
}
} else {
if (field.IsOptional()) {
code_ += " if let Some(f) = self.{{FIELD_NAME}}() {";
code_ += " s.serialize_field(\"{{FIELD_NAME}}\", &f)?;";
code_ += " } else {";
code_ += " s.skip_field(\"{{FIELD_NAME}}\")?;";
code_ += " }";
} else {
code_ +=
" s.serialize_field(\"{{FIELD_NAME}}\", "
"&self.{{FIELD_NAME}}())?;";
}
}
});
code_ += " s.end()";
code_ += " }";
code_ += "}";
code_ += "";
}
// Generate a builder struct:
code_ += "pub struct {{STRUCT_NAME}}Builder<'a: 'b, 'b> {";
@@ -2636,6 +2735,37 @@ class RustGenerator : public BaseGenerator {
code_ += " v.in_buffer::<Self>(pos)";
code_ += " }";
code_ += "}";
code_ += "";
// Implement serde::Serialize
if (parser_.opts.rust_serialize) {
const auto numFields = struct_def.fields.vec.size();
code_.SetValue("NUM_FIELDS", NumToString(numFields));
code_ += "impl Serialize for {{STRUCT_NAME}} {";
code_ +=
" fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>";
code_ += " where";
code_ += " S: Serializer,";
code_ += " {";
if (numFields == 0) {
code_ +=
" let s = serializer.serialize_struct(\"{{STRUCT_NAME}}\", 0)?;";
} else {
code_ +=
" let mut s = serializer.serialize_struct(\"{{STRUCT_NAME}}\", "
"{{NUM_FIELDS}})?;";
}
ForAllStructFields(struct_def, [&](const FieldDef &unused) {
(void)unused;
code_ +=
" s.serialize_field(\"{{FIELD_NAME}}\", "
"&self.{{FIELD_NAME}}())?;";
});
code_ += " s.end()";
code_ += " }";
code_ += "}";
code_ += "";
}
// Generate a constructor that takes all fields as arguments.
code_ += "impl<'a> {{STRUCT_NAME}} {";
@@ -2834,6 +2964,13 @@ class RustGenerator : public BaseGenerator {
code_ += indent + "use std::mem;";
code_ += indent + "use std::cmp::Ordering;";
code_ += "";
if (parser_.opts.rust_serialize) {
code_ += indent + "extern crate serde;";
code_ +=
indent +
"use self::serde::ser::{Serialize, Serializer, SerializeStruct};";
code_ += "";
}
code_ += indent + "extern crate flatbuffers;";
code_ += indent + "use self::flatbuffers::{EndianScalar, Follow};";
}

View File

@@ -220,8 +220,10 @@ class SwiftGenerator : public BaseGenerator {
IsEnum(field.value.type) ? "{{BASEVALUE}}" : "{{VALUETYPE}}";
code_ += "private var _{{VALUENAME}}: " + valueType;
auto accessing_value = IsEnum(field.value.type) ? ".value" : "";
auto base_value =
IsStruct(field.value.type) ? (type + "()") : field.value.constant;
auto is_bool = IsBool(field.value.type.base_type);
auto base_value = IsStruct(field.value.type) ? (type + "()")
: is_bool ? ("0" == field.value.constant ? "false" : "true")
: field.value.constant;
main_constructor.push_back("_" + name + " = " + name + accessing_value);
base_constructor.push_back("_" + name + " = " + base_value);
@@ -712,7 +714,8 @@ class SwiftGenerator : public BaseGenerator {
if (IsBool(field.value.type.base_type)) {
std::string default_value =
"0" == field.value.constant ? "false" : "true";
field.IsOptional() ? "nil"
: ("0" == field.value.constant ? "false" : "true");
code_.SetValue("CONSTANT", default_value);
code_.SetValue("VALUETYPE", "Bool");
code_ += GenReaderMainBody(optional) + "\\";

View File

@@ -265,6 +265,12 @@ struct JsonPrinter {
val = reinterpret_cast<const Struct *>(table)->GetStruct<const void *>(
fd.value.offset);
} else if (fd.flexbuffer && opts.json_nested_flexbuffers) {
// We could verify this FlexBuffer before access, but since this sits
// inside a FlatBuffer that we don't know wether it has been verified or
// not, there is little point making this part safer than the parent..
// The caller should really be verifying the whole.
// If the whole buffer is corrupt, we likely crash before we even get
// here.
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);

View File

@@ -291,8 +291,7 @@ class TsGenerator : public BaseGenerator {
std::string GenBBAccess() const { return "this.bb!"; }
std::string GenDefaultValue(const FieldDef &field, const std::string &context,
import_set &imports) {
std::string GenDefaultValue(const FieldDef &field, import_set &imports) {
if (field.IsScalarOptional()) { return "null"; }
const auto &value = field.value;
@@ -319,10 +318,7 @@ class TsGenerator : public BaseGenerator {
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)) + ")";
return "BigInt('" + value.constant + "')";
}
default: return value.constant;
@@ -347,8 +343,7 @@ class TsGenerator : public BaseGenerator {
switch (type.base_type) {
case BASE_TYPE_BOOL: return allowNull ? "boolean|null" : "boolean";
case BASE_TYPE_LONG:
case BASE_TYPE_ULONG:
return allowNull ? "flatbuffers.Long|null" : "flatbuffers.Long";
case BASE_TYPE_ULONG: return allowNull ? "bigint|null" : "bigint";
default:
if (IsScalar(type.base_type)) {
if (type.enum_def) {
@@ -911,8 +906,7 @@ class TsGenerator : public BaseGenerator {
// a string that contains values for things that can be created inline or
// the variable name from field_offset_decl
std::string field_offset_val;
const auto field_default_val =
GenDefaultValue(field, "flatbuffers", imports);
const auto field_default_val = GenDefaultValue(field, imports);
// Emit a scalar field
const auto is_string = IsString(field.value.type);
@@ -1232,7 +1226,7 @@ class TsGenerator : public BaseGenerator {
if (is_string) { index += ", optionalEncoding"; }
code += offset_prefix +
GenGetter(field.value.type, "(" + index + ")") + " : " +
GenDefaultValue(field, GenBBAccess(), imports);
GenDefaultValue(field, imports);
code += ";\n";
}
}
@@ -1328,7 +1322,7 @@ class TsGenerator : public BaseGenerator {
code += "false";
} else if (field.value.type.element == BASE_TYPE_LONG ||
field.value.type.element == BASE_TYPE_ULONG) {
code += GenBBAccess() + ".createLong(0, 0)";
code += "BigInt(0)";
} else if (IsScalar(field.value.type.element)) {
if (field.value.type.enum_def) {
code += field.value.constant;
@@ -1482,13 +1476,13 @@ class TsGenerator : public BaseGenerator {
code += "0";
} else if (HasNullDefault(field)) {
if (IsLong(field.value.type.base_type)) {
code += "builder.createLong(0, 0)";
code += "BigInt(0)";
} else {
code += "0";
}
} else {
if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; }
code += GenDefaultValue(field, "builder", imports);
code += GenDefaultValue(field, imports);
}
code += ");\n}\n\n";
@@ -1647,7 +1641,7 @@ class TsGenerator : public BaseGenerator {
std::string GetArgName(const FieldDef &field) {
auto argname = MakeCamel(field.name, false);
if (!IsScalar(field.value.type.base_type)) {
if (!IsScalar(field.value.type.base_type)) {
argname += "Offset";
} else {
argname = EscapeKeyword(argname);

View File

@@ -144,7 +144,10 @@ void Parser::Message(const std::string &msg) {
}
void Parser::Warning(const std::string &msg) {
if (!opts.no_warnings) Message("warning: " + msg);
if (!opts.no_warnings) {
Message("warning: " + msg);
has_warning_ = true; // for opts.warnings_as_errors
}
}
CheckedError Parser::Error(const std::string &msg) {
@@ -918,7 +921,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
}
if (!SupportsOptionalScalars()) {
return Error(
"Optional scalars are not yet supported in at least one the of "
"Optional scalars are not yet supported in at least one of "
"the specified programming languages.");
}
}
@@ -1125,6 +1128,9 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
}
uint8_t enum_idx;
if (vector_of_union_types) {
if (vector_of_union_types->size() <= count)
return Error("union types vector smaller than union values vector"
" for: " + field->name);
enum_idx = vector_of_union_types->Get(count);
} else {
ECHECK(atot(constant.c_str(), *this, &enum_idx));
@@ -1671,7 +1677,13 @@ 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));
if (opts.json_nested_legacy_flatbuffers) {
ECHECK(ParseAnyValue(val, field, fieldn, parent_struct_def, 0));
} else {
return Error(
"cannot parse nested_flatbuffer as bytes unless"
" --json-nested-bytes is set");
}
} else {
auto cursor_at_value_begin = cursor_;
ECHECK(SkipAnyJsonValue());
@@ -2152,10 +2164,14 @@ void EnumDef::SortByValue() {
auto &v = vals.vec;
if (IsUInt64())
std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) {
if (e1->GetAsUInt64() == e2->GetAsUInt64()) {
return e1->name < e2->name;
}
return e1->GetAsUInt64() < e2->GetAsUInt64();
});
else
std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) {
if (e1->GetAsInt64() == e2->GetAsInt64()) { return e1->name < e2->name; }
return e1->GetAsInt64() < e2->GetAsInt64();
});
}
@@ -3433,6 +3449,9 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
ECHECK(ParseDecl(source_filename));
}
}
if (opts.warnings_as_errors && has_warning_) {
return Error("treating warnings as errors, failed due to above warnings");
}
return NoError();
}

View File

@@ -505,8 +505,9 @@ bool VerifyStruct(flatbuffers::Verifier &v,
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());
return !offset ||
v.VerifyFieldStruct(reinterpret_cast<const uint8_t *>(&parent_table),
offset, obj.bytesize(), obj.minalign());
}
bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
@@ -553,7 +554,8 @@ 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;
if (!table.VerifyField<uoffset_t>(v, vec_field.offset(), sizeof(uoffset_t)))
return false;
switch (vec_field.type()->element()) {
case reflection::UType:
@@ -636,33 +638,45 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
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;
if (!table->VerifyField<uint8_t>(v, field_def->offset(),
sizeof(uint8_t)))
return false;
break;
case reflection::Bool:
case reflection::Byte:
case reflection::UByte:
if (!table->VerifyField<int8_t>(v, field_def->offset())) return false;
if (!table->VerifyField<int8_t>(v, field_def->offset(), sizeof(int8_t)))
return false;
break;
case reflection::Short:
case reflection::UShort:
if (!table->VerifyField<int16_t>(v, field_def->offset())) return false;
if (!table->VerifyField<int16_t>(v, field_def->offset(),
sizeof(int16_t)))
return false;
break;
case reflection::Int:
case reflection::UInt:
if (!table->VerifyField<int32_t>(v, field_def->offset())) return false;
if (!table->VerifyField<int32_t>(v, field_def->offset(),
sizeof(int32_t)))
return false;
break;
case reflection::Long:
case reflection::ULong:
if (!table->VerifyField<int64_t>(v, field_def->offset())) return false;
if (!table->VerifyField<int64_t>(v, field_def->offset(),
sizeof(int64_t)))
return false;
break;
case reflection::Float:
if (!table->VerifyField<float>(v, field_def->offset())) return false;
if (!table->VerifyField<float>(v, field_def->offset(), sizeof(float)))
return false;
break;
case reflection::Double:
if (!table->VerifyField<double>(v, field_def->offset())) return false;
if (!table->VerifyField<double>(v, field_def->offset(), sizeof(double)))
return false;
break;
case reflection::String:
if (!table->VerifyField<uoffset_t>(v, field_def->offset()) ||
if (!table->VerifyField<uoffset_t>(v, field_def->offset(),
sizeof(uoffset_t)) ||
!v.VerifyString(flatbuffers::GetFieldS(*table, *field_def))) {
return false;
}

View File

@@ -387,6 +387,16 @@ public struct ByteBuffer {
removing: _writerSize &- removeBytes)
}
/// Returns the written bytes into the ``ByteBuffer``
public var underlyingBytes: [UInt8] {
let cp = capacity &- writerIndex
let start = memory.advanced(by: writerIndex)
.bindMemory(to: UInt8.self, capacity: cp)
let ptr = UnsafeBufferPointer<UInt8>(start: start, count: cp)
return Array(ptr)
}
/// SkipPrefix Skips the first 4 bytes in case one of the following
/// functions are called `getPrefixedSizeCheckedRoot` & `getPrefixedSizeRoot`
/// which allows us to skip the first 4 bytes instead of recreating the buffer

View File

@@ -80,12 +80,7 @@ public struct FlatBufferBuilder {
/// Should only be used after ``finish(offset:addPrefix:)`` is called
public var sizedByteArray: [UInt8] {
assert(finished, "Data shouldn't be called before finish()")
let cp = _bb.capacity &- _bb.writerIndex
let start = _bb.memory.advanced(by: _bb.writerIndex)
.bindMemory(to: UInt8.self, capacity: cp)
let ptr = UnsafeBufferPointer(start: start, count: cp)
return Array(ptr)
return _bb.underlyingBytes
}
/// Returns the original ``ByteBuffer``

View File

@@ -8,6 +8,7 @@ cd ${swift_dir}/Tests/FlatBuffers.Test.SwiftTests
fbc --swift --gen-mutable --grpc --gen-json-emit --gen-object-api -I ${test_dir}/include_test ${test_dir}/monster_test.fbs ${test_dir}/union_vector/union_vector.fbs
fbc --swift --gen-json-emit ${test_dir}/optional_scalars.fbs
fbc --swift --gen-json-emit --gen-object-api ${test_dir}/more_defaults.fbs
fbc --swift --gen-json-emit --gen-mutable --gen-object-api ${test_dir}/MutatingBool.fbs
cd ${swift_dir}
cd ${swift_dir}/Sources/SwiftFlatBuffers

View File

@@ -1,49 +1,153 @@
// automatically generated by the FlatBuffers compiler, do not modify
// swiftlint:disable all
// swiftformat:disable all
import FlatBuffers
public struct Property: NativeStruct {
public struct Property: NativeStruct, Verifiable, FlatbuffersInitializable, NativeObject {
static func validateVersion() { FlatBuffersVersion_2_0_0() }
public var property: Bool
private var _property: Bool
public init(_ bb: ByteBuffer, o: Int32) {
let _accessor = Struct(bb: bb, position: o)
_property = _accessor.readBuffer(of: Bool.self, at: 0)
}
public init(property: Bool) {
_property = property
}
public init() {
_property = false
}
public init(_ _t: inout Property_Mutable) {
_property = _t.property
}
public var property: Bool { _property }
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
try verifier.inBuffer(position: position, of: Property.self)
}
}
extension Property: Encodable {
enum CodingKeys: String, CodingKey {
case property = "property"
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if property != false {
try container.encodeIfPresent(property, forKey: .property)
}
}
}
public struct Property_Mutable: FlatBufferObject {
static func validateVersion() { FlatBuffersVersion_2_0_0() }
public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Struct
static func validateVersion() { FlatBuffersVersion_2_0_0() }
public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Struct
public static var size = 1
public static var alignment = 1
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
public var property: Bool { return _accessor.readBuffer(of: Bool.self, at: 0) }
@discardableResult public func mutate(property: Bool) -> Bool { return _accessor.mutate(property, index: 0) }
public var property: Bool { return _accessor.readBuffer(of: Bool.self, at: 0) }
@discardableResult public func mutate(property: Bool) -> Bool { return _accessor.mutate(property, index: 0) }
public mutating func unpack() -> Property {
return Property(&self)
}
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout Property?) -> Offset {
guard var obj = obj else { return Offset() }
return pack(&builder, obj: &obj)
}
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout Property) -> Offset {
return builder.create(struct: obj)
}
}
public struct TestMutatingBool: FlatBufferObject {
public struct TestMutatingBool: FlatBufferObject, Verifiable, ObjectAPIPacker {
static func validateVersion() { FlatBuffersVersion_2_0_0() }
public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Table
static func validateVersion() { FlatBuffersVersion_2_0_0() }
public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Table
public static func getRootAsTestMutatingBool(bb: ByteBuffer) -> TestMutatingBool { return TestMutatingBool(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
public static func getRootAsTestMutatingBool(bb: ByteBuffer) -> TestMutatingBool { return TestMutatingBool(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
private init(_ t: Table) { _accessor = t }
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
private init(_ t: Table) { _accessor = t }
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
enum VTOFFSET: VOffset {
case b = 4
var v: Int32 { Int32(self.rawValue) }
var p: VOffset { self.rawValue }
}
private enum VTOFFSET: VOffset {
case b = 4
var v: Int32 { Int32(self.rawValue) }
var p: VOffset { self.rawValue }
}
public var b: Property? { let o = _accessor.offset(VTOFFSET.b.v); return o == 0 ? nil : _accessor.readBuffer(of: Property.self, at: o) }
public var mutableB: Property_Mutable? { let o = _accessor.offset(VTOFFSET.b.v); return o == 0 ? nil : Property_Mutable(_accessor.bb, o: o + _accessor.postion) }
public static func startTestMutatingBool(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
public static func add(b: Property?, _ fbb: inout FlatBufferBuilder) { guard let b = b else { return }; _ = fbb.create(struct: b, position: VTOFFSET.b.p) }
public static func endTestMutatingBool(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
public var b: Property? { let o = _accessor.offset(VTOFFSET.b.v); return o == 0 ? nil : _accessor.readBuffer(of: Property.self, at: o) }
public var mutableB: Property_Mutable? { let o = _accessor.offset(VTOFFSET.b.v); return o == 0 ? nil : Property_Mutable(_accessor.bb, o: o + _accessor.postion) }
public static func startTestMutatingBool(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
public static func add(b: Property?, _ fbb: inout FlatBufferBuilder) { guard let b = b else { return }; fbb.create(struct: b, position: VTOFFSET.b.p) }
public static func endTestMutatingBool(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
public static func createTestMutatingBool(
_ fbb: inout FlatBufferBuilder,
b: Property? = nil
) -> Offset {
let __start = TestMutatingBool.startTestMutatingBool(&fbb)
TestMutatingBool.add(b: b, &fbb)
return TestMutatingBool.endTestMutatingBool(&fbb, start: __start)
}
public mutating func unpack() -> TestMutatingBoolT {
return TestMutatingBoolT(&self)
}
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout TestMutatingBoolT?) -> Offset {
guard var obj = obj else { return Offset() }
return pack(&builder, obj: &obj)
}
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout TestMutatingBoolT) -> Offset {
let __root = TestMutatingBool.startTestMutatingBool(&builder)
TestMutatingBool.add(b: obj.b, &builder)
return TestMutatingBool.endTestMutatingBool(&builder, start: __root)
}
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
var _v = try verifier.visitTable(at: position)
try _v.visit(field: VTOFFSET.b.p, fieldName: "b", required: false, type: Property.self)
_v.finish()
}
}
extension TestMutatingBool: Encodable {
enum CodingKeys: String, CodingKey {
case b = "b"
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(b, forKey: .b)
}
}
public class TestMutatingBoolT: NativeObject {
public var b: Property?
public init(_ _t: inout TestMutatingBool) {
b = _t.b
}
public init() {
b = Property()
}
public func serialize() -> ByteBuffer { return serialize(type: TestMutatingBool.self) }
}

View File

@@ -1086,6 +1086,7 @@ public struct MyGame_Example_Monster: FlatBufferObject, Verifiable, ObjectAPIPac
case signedEnum = 100
case testrequirednestedflatbuffer = 102
case scalarKeySortedTables = 104
case nativeInline = 106
var v: Int32 { Int32(self.rawValue) }
var p: VOffset { self.rawValue }
}
@@ -1210,7 +1211,9 @@ public struct MyGame_Example_Monster: FlatBufferObject, Verifiable, ObjectAPIPac
public var scalarKeySortedTablesCount: Int32 { let o = _accessor.offset(VTOFFSET.scalarKeySortedTables.v); return o == 0 ? 0 : _accessor.vector(count: o) }
public func scalarKeySortedTables(at index: Int32) -> MyGame_Example_Stat? { let o = _accessor.offset(VTOFFSET.scalarKeySortedTables.v); return o == 0 ? nil : MyGame_Example_Stat(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) }
public func scalarKeySortedTablesBy(key: UInt16) -> MyGame_Example_Stat? { let o = _accessor.offset(VTOFFSET.scalarKeySortedTables.v); return o == 0 ? nil : MyGame_Example_Stat.lookupByKey(vector: _accessor.vector(at: o), key: key, fbb: _accessor.bb) }
public static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 51) }
public var nativeInline: MyGame_Example_Test? { let o = _accessor.offset(VTOFFSET.nativeInline.v); return o == 0 ? nil : _accessor.readBuffer(of: MyGame_Example_Test.self, at: o) }
public var mutableNativeInline: MyGame_Example_Test_Mutable? { let o = _accessor.offset(VTOFFSET.nativeInline.v); return o == 0 ? nil : MyGame_Example_Test_Mutable(_accessor.bb, o: o + _accessor.postion) }
public static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 52) }
public static func add(pos: MyGame_Example_Vec3?, _ fbb: inout FlatBufferBuilder) { guard let pos = pos else { return }; fbb.create(struct: pos, position: VTOFFSET.pos.p) }
public static func add(mana: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mana, def: 150, at: VTOFFSET.mana.p) }
public static func add(hp: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: hp, def: 100, at: VTOFFSET.hp.p) }
@@ -1271,6 +1274,7 @@ public struct MyGame_Example_Monster: FlatBufferObject, Verifiable, ObjectAPIPac
public static func add(signedEnum: MyGame_Example_Race, _ fbb: inout FlatBufferBuilder) { fbb.add(element: signedEnum.rawValue, def: -1, at: VTOFFSET.signedEnum.p) }
public static func addVectorOf(testrequirednestedflatbuffer: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: testrequirednestedflatbuffer, at: VTOFFSET.testrequirednestedflatbuffer.p) }
public static func addVectorOf(scalarKeySortedTables: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: scalarKeySortedTables, at: VTOFFSET.scalarKeySortedTables.p) }
public static func add(nativeInline: MyGame_Example_Test?, _ fbb: inout FlatBufferBuilder) { guard let nativeInline = nativeInline else { return }; fbb.create(struct: nativeInline, position: VTOFFSET.nativeInline.p) }
public static func endMonster(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); fbb.require(table: end, fields: [10]); return end }
public static func createMonster(
_ fbb: inout FlatBufferBuilder,
@@ -1323,7 +1327,8 @@ public struct MyGame_Example_Monster: FlatBufferObject, Verifiable, ObjectAPIPac
vectorOfEnumsVectorOffset vectorOfEnums: Offset = Offset(),
signedEnum: MyGame_Example_Race = .none_,
testrequirednestedflatbufferVectorOffset testrequirednestedflatbuffer: Offset = Offset(),
scalarKeySortedTablesVectorOffset scalarKeySortedTables: Offset = Offset()
scalarKeySortedTablesVectorOffset scalarKeySortedTables: Offset = Offset(),
nativeInline: MyGame_Example_Test? = nil
) -> Offset {
let __start = MyGame_Example_Monster.startMonster(&fbb)
MyGame_Example_Monster.add(pos: pos, &fbb)
@@ -1376,6 +1381,7 @@ public struct MyGame_Example_Monster: FlatBufferObject, Verifiable, ObjectAPIPac
MyGame_Example_Monster.add(signedEnum: signedEnum, &fbb)
MyGame_Example_Monster.addVectorOf(testrequirednestedflatbuffer: testrequirednestedflatbuffer, &fbb)
MyGame_Example_Monster.addVectorOf(scalarKeySortedTables: scalarKeySortedTables, &fbb)
MyGame_Example_Monster.add(nativeInline: nativeInline, &fbb)
return MyGame_Example_Monster.endMonster(&fbb, start: __start)
}
public static func sortVectorOfMonster(offsets:[Offset], _ fbb: inout FlatBufferBuilder) -> Offset {
@@ -1532,6 +1538,7 @@ public struct MyGame_Example_Monster: FlatBufferObject, Verifiable, ObjectAPIPac
MyGame_Example_Monster.add(signedEnum: obj.signedEnum, &builder)
MyGame_Example_Monster.addVectorOf(testrequirednestedflatbuffer: __testrequirednestedflatbuffer, &builder)
MyGame_Example_Monster.addVectorOf(scalarKeySortedTables: __scalarKeySortedTables, &builder)
MyGame_Example_Monster.add(nativeInline: obj.nativeInline, &builder)
return MyGame_Example_Monster.endMonster(&builder, start: __root)
}
@@ -1617,6 +1624,7 @@ public struct MyGame_Example_Monster: FlatBufferObject, Verifiable, ObjectAPIPac
try _v.visit(field: VTOFFSET.signedEnum.p, fieldName: "signedEnum", required: false, type: MyGame_Example_Race.self)
try _v.visit(field: VTOFFSET.testrequirednestedflatbuffer.p, fieldName: "testrequirednestedflatbuffer", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
try _v.visit(field: VTOFFSET.scalarKeySortedTables.p, fieldName: "scalarKeySortedTables", required: false, type: ForwardOffset<Vector<ForwardOffset<MyGame_Example_Stat>, MyGame_Example_Stat>>.self)
try _v.visit(field: VTOFFSET.nativeInline.p, fieldName: "nativeInline", required: false, type: MyGame_Example_Test.self)
_v.finish()
}
}
@@ -1674,6 +1682,7 @@ extension MyGame_Example_Monster: Encodable {
case signedEnum = "signed_enum"
case testrequirednestedflatbuffer = "testrequirednestedflatbuffer"
case scalarKeySortedTables = "scalar_key_sorted_tables"
case nativeInline = "native_inline"
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
@@ -1884,6 +1893,7 @@ extension MyGame_Example_Monster: Encodable {
try contentEncoder.encode(type)
}
}
try container.encodeIfPresent(nativeInline, forKey: .nativeInline)
}
}
@@ -1936,6 +1946,7 @@ public class MyGame_Example_MonsterT: NativeObject {
public var signedEnum: MyGame_Example_Race
public var testrequirednestedflatbuffer: [UInt8]
public var scalarKeySortedTables: [MyGame_Example_StatT?]
public var nativeInline: MyGame_Example_Test?
public init(_ _t: inout MyGame_Example_Monster) {
pos = _t.pos
@@ -2085,6 +2096,7 @@ public class MyGame_Example_MonsterT: NativeObject {
var __v_ = _t.scalarKeySortedTables(at: index)
scalarKeySortedTables.append(__v_?.unpack())
}
nativeInline = _t.nativeInline
}
public init() {
@@ -2132,6 +2144,7 @@ public class MyGame_Example_MonsterT: NativeObject {
signedEnum = .none_
testrequirednestedflatbuffer = []
scalarKeySortedTables = []
nativeInline = MyGame_Example_Test()
}
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Monster.self) }

View File

@@ -111,7 +111,7 @@ public struct optional_scalars_ScalarStuff: FlatBufferObject, Verifiable {
public var maybeF64: Double? { let o = _accessor.offset(VTOFFSET.maybeF64.v); return o == 0 ? nil : _accessor.readBuffer(of: Double.self, at: o) }
public var defaultF64: Double { let o = _accessor.offset(VTOFFSET.defaultF64.v); return o == 0 ? 42.0 : _accessor.readBuffer(of: Double.self, at: o) }
public var justBool: Bool { let o = _accessor.offset(VTOFFSET.justBool.v); return o == 0 ? false : 0 != _accessor.readBuffer(of: Byte.self, at: o) }
public var maybeBool: Bool? { let o = _accessor.offset(VTOFFSET.maybeBool.v); return o == 0 ? true : 0 != _accessor.readBuffer(of: Byte.self, at: o) }
public var maybeBool: Bool? { let o = _accessor.offset(VTOFFSET.maybeBool.v); return o == 0 ? nil : 0 != _accessor.readBuffer(of: Byte.self, at: o) }
public var defaultBool: Bool { let o = _accessor.offset(VTOFFSET.defaultBool.v); return o == 0 ? true : 0 != _accessor.readBuffer(of: Byte.self, at: o) }
public var justEnum: optional_scalars_OptionalByte { let o = _accessor.offset(VTOFFSET.justEnum.v); return o == 0 ? .none_ : optional_scalars_OptionalByte(rawValue: _accessor.readBuffer(of: Int8.self, at: o)) ?? .none_ }
public var maybeEnum: optional_scalars_OptionalByte? { let o = _accessor.offset(VTOFFSET.maybeEnum.v); return o == 0 ? nil : optional_scalars_OptionalByte(rawValue: _accessor.readBuffer(of: Int8.self, at: o)) ?? nil }

View File

@@ -116,13 +116,13 @@ namespace FlatBuffers.Test
// Dump to output directory so we can inspect later, if needed
#if ENABLE_SPAN_T
var data = fbb.DataBuffer.ToSizedArray();
string filename = @".tmp/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
string filename = @"monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
File.WriteAllBytes(filename, data);
#else
using (var ms = fbb.DataBuffer.ToMemoryStream(fbb.DataBuffer.Position, fbb.Offset))
{
var data = ms.ToArray();
string filename = @".tmp/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
string filename = @"monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
File.WriteAllBytes(filename, data);
}
#endif

View File

@@ -73,6 +73,11 @@ function createMonster(fbb) {
fbb.createString('test2')
]);
var testVectorOfLongs = Monster.createVectorOfLongsVector(fbb, [
1n,
101010100n
]);
Monster.startMonster(fbb);
Monster.addPos(fbb, Vec3.createVec3(fbb, 1, 2, 3, 3, Color.Green, 5, 6));
Monster.addHp(fbb, 80);
@@ -82,6 +87,7 @@ function createMonster(fbb) {
Monster.addTest(fbb, mon2);
Monster.addTest4(fbb, test4);
Monster.addTestarrayofstring(fbb, testArrayOfString);
Monster.addVectorOfLongs(fbb, testVectorOfLongs);
Monster.addTestbool(fbb, true);
var mon = Monster.endMonster(fbb);
@@ -94,7 +100,7 @@ function serializeAndTest(fbb) {
// parser may serialize in a slightly different order than the above
// JavaScript code. They are functionally equivalent though.
fs.writeFileSync('monsterdata_javascript_wire.mon', new Buffer(fbb.asUint8Array()));
fs.writeFileSync('monsterdata_javascript_wire.mon', Buffer.from(fbb.asUint8Array()));
// Tests mutation first. This will verify that we did not trample any other
// part of the byte buffer.
@@ -207,6 +213,12 @@ function testBuffer(bb) {
}
assert.strictEqual(invsum2, 10);
let longSum = 0n;
for (let idx = 0; idx < monster.vectorOfLongsLength(); ++idx) {
longSum += monster.vectorOfLongs(idx);
}
assert.strictEqual(longSum, 101010101n);
var test_0 = monster.test4(0);
var test_1 = monster.test4(1);
assert.strictEqual(monster.test4Length(), 2);
@@ -239,8 +251,8 @@ function test64bit() {
var mon2 = Monster.endMonster(fbb);
Stat.startStat(fbb);
// 2541551405100253985 = 0x87654321(low part) + 0x23456789 * 0x100000000(high part);
Stat.addVal(fbb, new flatbuffers.Long(0x87654321, 0x23456789)); // the low part is Uint32
// 2541551405100253985 = 0x2345678987654321
Stat.addVal(fbb, 0x2345678987654321n);
var stat = Stat.endStat(fbb);
Monster.startMonster(fbb);
@@ -261,15 +273,14 @@ function test64bit() {
var stat = mon.testempty();
assert.strictEqual(stat != null, true);
assert.strictEqual(stat.val() != null, true);
assert.strictEqual(stat.val().toFloat64(), 2541551405100253985);
assert.strictEqual(stat.val(), 2541551405100253985n);
var mon2 = mon.enemy();
assert.strictEqual(mon2 != null, true);
stat = mon2.testempty();
assert.strictEqual(stat != null, true);
assert.strictEqual(stat.val() != null, true);
assert.strictEqual(stat.val().low, 0); // default value
assert.strictEqual(stat.val().high, 0);
assert.strictEqual(stat.val(), 0n); // default value
}
function testUnicode() {
@@ -280,17 +291,17 @@ function testUnicode() {
function testReadingUnicode(bb) {
var monster = Monster.getRootAsMonster(bb);
assert.strictEqual(monster.name(), json.name);
assert.deepEqual(new Buffer(monster.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(json.name));
assert.deepEqual(Buffer.from(monster.name(flatbuffers.Encoding.UTF8_BYTES)), Buffer.from(json.name));
assert.strictEqual(monster.testarrayoftablesLength(), json.testarrayoftables.length);
json.testarrayoftables.forEach(function(table, i) {
var value = monster.testarrayoftables(i);
assert.strictEqual(value.name(), table.name);
assert.deepEqual(new Buffer(value.name(flatbuffers.Encoding.UTF8_BYTES)), new Buffer(table.name));
assert.deepEqual(Buffer.from(value.name(flatbuffers.Encoding.UTF8_BYTES)), Buffer.from(table.name));
});
assert.strictEqual(monster.testarrayofstringLength(), json.testarrayofstring.length);
json.testarrayofstring.forEach(function(string, i) {
assert.strictEqual(monster.testarrayofstring(i), string);
assert.deepEqual(new Buffer(monster.testarrayofstring(i, flatbuffers.Encoding.UTF8_BYTES)), new Buffer(string));
assert.deepEqual(Buffer.from(monster.testarrayofstring(i, flatbuffers.Encoding.UTF8_BYTES)), Buffer.from(string));
});
}
testReadingUnicode(new flatbuffers.ByteBuffer(new Uint8Array(correct)));
@@ -299,7 +310,7 @@ function testUnicode() {
var fbb = new flatbuffers.Builder();
var name = fbb.createString(json.name);
var testarrayoftablesOffsets = json.testarrayoftables.map(function(table) {
var name = fbb.createString(new Uint8Array(new Buffer(table.name)));
var name = fbb.createString(new Uint8Array(Buffer.from(table.name)));
Monster.startMonster(fbb);
Monster.addName(fbb, name);
return Monster.endMonster(fbb);
@@ -359,8 +370,8 @@ function fuzzTest1() {
var ushort_val = 0xFEEE;
var int_val = 0x83333333 | 0;
var uint_val = 0xFDDDDDDD;
var long_val = new flatbuffers.Long(0x44444444, 0x84444444);
var ulong_val = new flatbuffers.Long(0xCCCCCCCC, 0xFCCCCCCC);
var long_val = BigInt.asIntN(64, 0x8444444444444444n);
var ulong_val = BigInt.asUintN(64, 0xFCCCCCCCCCCCCCCCn);
var float_val = new Float32Array([3.14159])[0];
var double_val = 3.14159265359;
@@ -381,16 +392,16 @@ function fuzzTest1() {
for (var f = 0; f < fields_per_object; f++) {
var choice = lcg_rand() % test_values_max;
switch (choice) {
case 0: builder.addFieldInt8(f, bool_val, 0); break;
case 1: builder.addFieldInt8(f, char_val, 0); break;
case 2: builder.addFieldInt8(f, uchar_val, 0); break;
case 3: builder.addFieldInt16(f, short_val, 0); break;
case 0: builder.addFieldInt8(f, bool_val, 0); break;
case 1: builder.addFieldInt8(f, char_val, 0); break;
case 2: builder.addFieldInt8(f, uchar_val, 0); break;
case 3: builder.addFieldInt16(f, short_val, 0); break;
case 4: builder.addFieldInt16(f, ushort_val, 0); break;
case 5: builder.addFieldInt32(f, int_val, 0); break;
case 6: builder.addFieldInt32(f, uint_val, 0); break;
case 7: builder.addFieldInt64(f, long_val, flatbuffers.Long.ZERO); break;
case 8: builder.addFieldInt64(f, ulong_val, flatbuffers.Long.ZERO); break;
case 9: builder.addFieldFloat32(f, float_val, 0); break;
case 5: builder.addFieldInt32(f, int_val, 0); break;
case 6: builder.addFieldInt32(f, uint_val, 0); break;
case 7: builder.addFieldInt64(f, long_val, 0n); break;
case 8: builder.addFieldInt64(f, ulong_val, 0n); break;
case 9: builder.addFieldFloat32(f, float_val, 0); break;
case 10: builder.addFieldFloat64(f, double_val, 0); break;
}
}
@@ -423,8 +434,8 @@ function fuzzTest1() {
case 4: assert.strictEqual(view.getUint16(field_offset, true), ushort_val); break;
case 5: assert.strictEqual(view.getInt32(field_offset, true), int_val); break;
case 6: assert.strictEqual(view.getUint32(field_offset, true), uint_val); break;
case 7: assert.strictEqual(view.getInt32(field_offset, true), long_val.low); assert.strictEqual(view.getInt32(field_offset + 4, true), long_val.high); break;
case 8: assert.strictEqual(view.getInt32(field_offset, true), ulong_val.low); assert.strictEqual(view.getInt32(field_offset + 4, true), ulong_val.high); break;
case 7: assert.strictEqual(view.getBigInt64(field_offset, true), long_val); break;
case 8: assert.strictEqual(view.getBigUint64(field_offset, true), ulong_val); break;
case 9: assert.strictEqual(view.getFloat32(field_offset, true), float_val); break;
case 10: assert.strictEqual(view.getFloat64(field_offset, true), double_val); break;
}

8
tests/MutatingBool.fbs Normal file
View File

@@ -0,0 +1,8 @@
struct Property {
property: bool;
}
table TestMutatingBool {
b: Property;
}

View File

@@ -7,7 +7,6 @@ import kotlin.math.sign
import com.google.flatbuffers.*
@Suppress("unused")
@ExperimentalUnsignedTypes
class Ability : Struct() {
fun __init(_i: Int, _bb: ByteBuffer) {

View File

@@ -3,7 +3,7 @@
Automatically generated by the FlatBuffers compiler, do not modify.
Or modify. I'm a message, not a cop.
flatc version: 2.0.5
flatc version: 2.0.6
Declared by : //monster_test.fbs
Rooting type : MyGame.Example.Monster (//monster_test.fbs)

Some files were not shown because too many files have changed in this diff Show More