diff --git a/.bazelrc b/.bazelrc index a8f33c98a..f9f47a742 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1 +1,4 @@ +# We cannot use "common" here because the "version" command doesn't support +# --deleted_packages. We need to specify it for both build and query instead. build --deleted_packages=tests/ts/bazel_repository_test_dir +query --deleted_packages=tests/ts/bazel_repository_test_dir diff --git a/.github/labeler.yml b/.github/labeler.yml index dcab0447e..e3da18c1e 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -48,11 +48,11 @@ java: kotlin: - '**/*.kt' - src/idl_gen_kotlin.cpp + - src/idl_gen_kotlin_kmp.cpp lua: - '**/*.lua' - lua/**/* - - src/idl_gen_lua.cpp - src/bfbs_gen_lua.cpp lobster: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cc2a614fb..dd59a2438 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,6 +76,28 @@ jobs: - name: build run: make -j + build-linux-out-of-source: + name: Build Linux with out-of-source build location + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: make build directory + run: mkdir build + - name: cmake + working-directory: build + run: > + CXX=clang++-12 cmake .. -G "Unix Makefiles" -DFLATBUFFERS_STRICT_MODE=ON + -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_CPP_STD=17 + - name: build + working-directory: build + run: make -j + - name: test + working-directory: build + run: pwd && ./flattests + - name: test C++17 + working-directory: build + run: ./flattests_cpp17 + build-linux-cpp-std: name: Build Linux C++ runs-on: ubuntu-latest @@ -400,9 +422,14 @@ jobs: with: distribution: 'temurin' java-version: '11' + - name: Build flatc + run: | + cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . + make -j + echo "${PWD}" >> $GITHUB_PATH - name: Build working-directory: kotlin - run: ./gradlew clean iosX64Test macosX64Test + run: ./gradlew clean iosSimulatorArm64Test macosX64Test macosArm64Test build-kotlin-linux: name: Build Kotlin Linux @@ -415,6 +442,11 @@ jobs: distribution: 'temurin' java-version: '11' - uses: gradle/wrapper-validation-action@v1.0.5 + - name: Build flatc + run: | + cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . + make -j + echo "${PWD}" >> $GITHUB_PATH - name: Build working-directory: kotlin # we are using docker's version of gradle @@ -422,20 +454,32 @@ jobs: # gradlew run: gradle jvmMainClasses jvmTest jsTest jsBrowserTest - build-rust: - name: Build Rust + build-rust-linux: + name: Build Rust Linux runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: test working-directory: tests run: bash RustTest.sh + + build-rust-windows: + name: Build Rust Windows + runs-on: windows-2019 + steps: + - uses: actions/checkout@v3 + - name: test + working-directory: tests + run: ./RustTest.bat build-python: name: Build Python runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - 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 -DFLATBUFFERS_STRICT_MODE=ON . && make -j - name: test working-directory: tests run: bash PythonTest.sh diff --git a/.gitignore b/.gitignore index 4d83964e5..828ca1d61 100644 --- a/.gitignore +++ b/.gitignore @@ -151,3 +151,5 @@ flatbuffers.pc # https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_BASE_DIR cmake-build-debug/ _deps/ +**/.gradle/** +kotlin/**/generated diff --git a/CHANGELOG.md b/CHANGELOG.md index 061229ede..145c62b10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,58 @@ All major or breaking changes will be documented in this file, as well as any new features that should be highlighted. Minor fixes or improvements are not necessarily listed. +## [23.5.26 (May 26 2023)](https://github.com/google/flatbuffers/releases/tag/v23.5.26) + +* Mostly bug fixing for 64-bit support +* Adds support for specifying underling type of unions in C++ and TS/JS (#7954) + +## [23.5.9 (May 9 2023)](https://github.com/google/flatbuffers/releases/tag/v23.5.9) + +* 64-bit support for C++ (#7935) + +## [23.5.8 (May 8 2023)](https://github.com/google/flatbuffers/releases/tag/v23.5.8) + +* add key_field to compiled tests +* Add golden language directory +* Rework cmake flatc codegeneration (#7938) +* remove defining generated files in test srcs +* Add binary schema reflection (#7932) +* Migrate from rules_nodejs to rules_js/rules_ts (take 2) (#7928) +* `flat_buffers.dart`: mark const variable finals for internal Dart linters +* fixed some windows warnings (#7929) +* inject no long for FBS generation to remove logs in flattests (#7926) +* Revert "Migrate from rules_nodejs to rules_js/rules_ts (#7923)" (#7927) +* Migrate from rules_nodejs to rules_js/rules_ts (#7923) +* Only generate @kotlin.ExperimentalUnsigned annotation on create*Vector methods having an unsigned array type parameter. (#7881) +* additional check for absl::string_view availability (#7897) +* Optionally generate Python type annotations (#7858) +* Replace deprecated command with environment file (#7921) +* drop glibc from runtime dependencies (#7906) +* Make JSON supporting advanced union features (#7869) +* Allow to use functions from `BuildFlatBuffers.cmake` from a flatbuffers installation installed with CMake. (#7912) +* TS/JS: Use TypeError instead of Error when appropriate (#7910) +* Go: make generated code more compliant to "go fmt" (#7907) +* Support file_identifier in Go (#7904) +* Optionally generate type prefixes and suffixes for python code (#7857) +* Go: add test for FinishWithFileIdentifier (#7905) +* Fix go_sample.sh (#7903) +* [TS/JS] Upgrade dependencies (#7889) +* Add a FileWriter interface (#7821) +* TS/JS: Use minvalue from enum if not found (#7888) +* [CS] Verifier (#7850) +* README.md: PyPI case typo (#7880) +* Update go documentation link to point to root module (#7879) +* use Bool for flatbuffers bool instead of Byte (#7876) +* fix using null string in vector (#7872) +* Add `flatbuffers-64` branch to CI for pushes +* made changes to the rust docs so they would compile. new_with_capacity is deprecated should use with_capacity, get_root_as_monster should be root_as_monster (#7871) +* Adding comment for code clarification (#7856) +* ToCamelCase() when kLowerCamel now converts first char to lower. (#7838) +* Fix help output for --java-checkerframework (#7854) +* Update filename to README.md and improve formatting (#7855) +* Update stale.yml +* Updated remaining usages of LICENSE.txt + ## [23.3.3 (Mar 3 2023)](https://github.com/google/flatbuffers/releases/tag/v23.3.3) * Refactoring of `flatc` generators to use an interface (#7797). diff --git a/CMake/Version.cmake b/CMake/Version.cmake index ac145ba7f..f50e31a61 100644 --- a/CMake/Version.cmake +++ b/CMake/Version.cmake @@ -1,6 +1,6 @@ set(VERSION_MAJOR 23) -set(VERSION_MINOR 3) -set(VERSION_PATCH 3) +set(VERSION_MINOR 5) +set(VERSION_PATCH 26) set(VERSION_COMMIT 0) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b65c20e5..6a2e83499 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ 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_FLATHASH "Enable the build of flathash" OFF) option(FLATBUFFERS_BUILD_BENCHMARKS "Enable the build of flatbenchmark." OFF) option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF) @@ -160,13 +160,13 @@ set(FlatBuffers_Compiler_SRCS src/idl_gen_csharp.cpp src/idl_gen_dart.cpp src/idl_gen_kotlin.cpp + src/idl_gen_kotlin_kmp.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 @@ -234,31 +234,10 @@ set(FlatBuffers_Tests_SRCS tests/native_type_test_impl.cpp tests/alignment_test.h tests/alignment_test.cpp + tests/64bit/offset64_test.h + tests/64bit/offset64_test.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 - # file generate by running compiler on tests/native_inline_table_test.fbs - ${CMAKE_CURRENT_BINARY_DIR}/tests/native_inline_table_test_generated.h - # file generate by running compiler on tests/alignment_test.fbs - ${CMAKE_CURRENT_BINARY_DIR}/tests/alignment_test_generated.h - # file generate by running compiler on tests/key_field/key_field_sample.fbs - ${CMAKE_CURRENT_BINARY_DIR}/tests/key_field/key_field_sample_generated.h ) set(FlatBuffers_Tests_CPP17_SRCS @@ -266,32 +245,20 @@ set(FlatBuffers_Tests_CPP17_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 @@ -307,8 +274,6 @@ set(FlatBuffers_GRPCTest_SRCS 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 ) # TODO(dbaileychess): Figure out how this would now work. I posted a question on @@ -523,145 +488,89 @@ if(FLATBUFFERS_BUILD_SHAREDLIB) 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}'") +function(compile_schema SRC_FBS OPT OUT_GEN_FILE) 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}) + ${OPT} + -o "${SRC_FBS_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}" + DEPENDS flatc ${SRC_FBS} + COMMENT "flatc generation: `${SRC_FBS}` -> `${GEN_HEADER}`" + ) + set(${OUT_GEN_FILE} ${GEN_HEADER} PARENT_SCOPE) endfunction() -function(compile_flatbuffers_schema_to_cpp SRC_FBS) - compile_flatbuffers_schema_to_cpp_opt(${SRC_FBS} "--no-includes;--gen-compare") +function(compile_schema_for_test SRC_FBS OPT) + compile_schema("${SRC_FBS}" "${OPT}" GEN_FILE) + target_sources(flattests PRIVATE ${GEN_FILE}) 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 "${CMAKE_CURRENT_SOURCE_DIR}/${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}) +function(compile_schema_for_samples SRC_FBS OPT) + compile_schema("${SRC_FBS}" "${OPT}" GEN_FILE) + target_sources(flatsample PRIVATE ${GEN_FILE}) endfunction() 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;") - 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") - compile_flatbuffers_schema_to_cpp(tests/native_inline_table_test.fbs "--gen-compare") - compile_flatbuffers_schema_to_cpp(tests/alignment_test.fbs "--gen-compare") - compile_flatbuffers_schema_to_cpp(tests/key_field/key_field_sample.fbs) - 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}) target_link_libraries(flattests PRIVATE $) + target_include_directories(flattests PUBLIC + # Ideally everything is fully qualified from the root directories + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + # TODO(derekbailey): update includes to fully qualify src/ and tests/ + src + tests + ${CMAKE_CURRENT_BINARY_DIR}/tests + ) - add_dependencies(flattests generated_code) + # Have tests load data from the source directory, not the build directory. + add_definitions(-DFLATBUFFERS_TEST_PATH_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/) + + # The flattest target needs some generated files + SET(FLATC_OPT --cpp --gen-mutable --gen-object-api --reflect-names) + SET(FLATC_OPT_COMP ${FLATC_OPT};--gen-compare) + SET(FLATC_OPT_SCOPED_ENUMS ${FLATC_OPT_COMP};--scoped-enums) + + compile_schema_for_test(tests/alignment_test.fbs "${FLATC_OPT_COMP}") + compile_schema_for_test(tests/arrays_test.fbs "${FLATC_OPT_SCOPED_ENUMS}") + compile_schema_for_test(tests/native_inline_table_test.fbs "${FLATC_OPT_COMP}") + compile_schema_for_test(tests/native_type_test.fbs "${FLATC_OPT}") + compile_schema_for_test(tests/key_field/key_field_sample.fbs "${FLATC_OPT_COMP}") + compile_schema_for_test(tests/64bit/test_64bit.fbs "${FLATC_OPT_COMP};--bfbs-gen-embed") + compile_schema_for_test(tests/64bit/evolution/v1.fbs "${FLATC_OPT_COMP}") + compile_schema_for_test(tests/64bit/evolution/v2.fbs "${FLATC_OPT_COMP}") + compile_schema_for_test(tests/union_underlying_type_test.fbs "${FLATC_OPT_SCOPED_ENUMS}") 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}) - target_link_libraries(flatsamplebinary PRIVATE $) - add_dependencies(flatsamplebinary generated_code) - add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS}) - target_link_libraries(flatsampletext PRIVATE $) - add_dependencies(flatsampletext generated_code) - add_executable(flatsamplebfbs ${FlatBuffers_Sample_BFBS_SRCS}) - target_link_libraries(flatsamplebfbs PRIVATE $) - add_dependencies(flatsamplebfbs generated_code) + + # Add a library so there is a single target that the generated samples can + # link too. + add_library(flatsample INTERFACE) + + # Since flatsample has no sources, we have to explicitly set the linker lang. + set_target_properties(flatsample PROPERTIES LINKER_LANGUAGE CXX) + + compile_schema_for_samples(samples/monster.fbs "${FLATC_OPT_COMP}") + + target_link_libraries(flatsamplebinary PRIVATE $ flatsample) + target_link_libraries(flatsampletext PRIVATE $ flatsample) + target_link_libraries(flatsamplebfbs PRIVATE $ flatsample) if(FLATBUFFERS_BUILD_CPP17) - # Don't generate header for flattests_cpp17 target. - # This target uses "generated_cpp17/monster_test_generated.h" add_executable(flattests_cpp17 ${FlatBuffers_Tests_CPP17_SRCS}) - add_dependencies(flattests_cpp17 generated_code) target_link_libraries(flattests_cpp17 PRIVATE $) + target_include_directories(flattests_cpp17 PUBLIC src tests) target_compile_features(flattests_cpp17 PRIVATE cxx_std_17) # requires cmake 3.8 if(FLATBUFFERS_CODE_SANITIZE) @@ -685,7 +594,6 @@ if(FLATBUFFERS_BUILD_GRPCTEST) find_package(protobuf CONFIG REQUIRED) find_package(gRPC CONFIG REQUIRED) add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS}) - add_dependencies(grpctest generated_code) target_link_libraries(grpctext PRIVATE $ @@ -778,16 +686,6 @@ if(FLATBUFFERS_BUILD_TESTS) 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) diff --git a/FlatBuffers.podspec b/FlatBuffers.podspec index 0a26d9f17..cecb1137e 100644 --- a/FlatBuffers.podspec +++ b/FlatBuffers.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FlatBuffers' - s.version = '23.3.3' + s.version = '23.5.26' s.summary = 'FlatBuffers: Memory Efficient Serialization Library' s.description = "FlatBuffers is a cross platform serialization library architected for diff --git a/README.md b/README.md index 1fb2fe0c6..875c73bb9 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,47 @@ **FlatBuffers** is a cross platform serialization library architected for maximum memory efficiency. It allows you to directly access serialized data without parsing/unpacking it first, while still having great forwards/backwards compatibility. +## Quick Start + +1. Build the compiler for flatbuffers (`flatc`) + + Use `cmake` to create the build files for your platform and then perform the compliation (Linux example). + + ``` + cmake -G "Unix Makefiles" + make -j + ``` + +2. Define your flatbuffer schema (`.fbs`) + + Write the [schema](https://flatbuffers.dev/flatbuffers_guide_writing_schema.html) to define the data you want to serialize. See [monster.fbs](https://github.com/google/flatbuffers/blob/master/samples/monster.fbs) for an example. + +3. Generate code for your language(s) + + Use the `flatc` compiler to take your schema and generate language-specific code: + + ``` + ./flatc --cpp --rust monster.fbs + ``` + + Which generates `monster_generated.h` and `monster_generated.rs` files. + +4. Serialize data + + Use the generated code, as well as the `FlatBufferBuilder` to construct your serialized buffer. ([`C++` example](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.cpp#L24-L56)) + +5. Transmit/store/save Buffer + + Use your serialized buffer however you want. Send it to someone, save it for later, etc... + +6. Read the data + + Use the generated accessors to read the data from the serialized buffer. + + It doesn't need to be the same language/schema version, FlatBuffers ensures the data is readable across languages and schema versions. See the [`Rust` example](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs#L92-L106) reading the data written by `C++`. + +## Documentation + **Go to our [landing page][] to browse our documentation.** ## Supported operating systems @@ -46,7 +87,7 @@ Code generation and runtime libraries for many popular languages. ## Versioning -FlatBuffers does not follow traditional Semver versioning (see [rationale](https://github.com/google/flatbuffers/wiki/Versioning)) but rather uses a format of the date of the release. +FlatBuffers does not follow traditional SemVer versioning (see [rationale](https://github.com/google/flatbuffers/wiki/Versioning)) but rather uses a format of the date of the release. ## Contribution diff --git a/WORKSPACE b/WORKSPACE index 9f70edd44..d7a8b2ca7 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -148,6 +148,7 @@ esbuild_register_toolchains( http_file( name = "bazel_linux_x86_64", downloaded_file_path = "bazel", + executable = True, sha256 = "e89747d63443e225b140d7d37ded952dacea73aaed896bca01ccd745827c6289", urls = [ "https://github.com/bazelbuild/bazel/releases/download/6.1.2/bazel-6.1.2-linux-x86_64", diff --git a/android/.project b/android/.project index 3ed7298f8..17f0659d4 100644 --- a/android/.project +++ b/android/.project @@ -10,7 +10,7 @@ - 1677235311958 + 1672434305228 30 diff --git a/android/app/src/main/cpp/CMakeLists.txt b/android/app/src/main/cpp/CMakeLists.txt index f30dd4a0a..abb8250bd 100644 --- a/android/app/src/main/cpp/CMakeLists.txt +++ b/android/app/src/main/cpp/CMakeLists.txt @@ -48,7 +48,6 @@ find_library( # Sets the name of the path variable. target_link_libraries( # Specifies the target library. native-lib flatbuffers - flatbuffers_tests # Links the target library to the log library # included in the NDK. ${log-lib} ) diff --git a/android/app/src/main/cpp/flatbuffers/CMakeLists.txt b/android/app/src/main/cpp/flatbuffers/CMakeLists.txt index ee9271532..144523ee8 100644 --- a/android/app/src/main/cpp/flatbuffers/CMakeLists.txt +++ b/android/app/src/main/cpp/flatbuffers/CMakeLists.txt @@ -48,26 +48,9 @@ set(FlatBuffers_Library_SRCS ${FLATBUFFERS_SRC}/src/code_generators.cpp ) -set(FlatBuffers_Test_SRCS - ${FLATBUFFERS_SRC}/tests/test.cpp - ${FLATBUFFERS_SRC}/tests/test_assert.h - ${FLATBUFFERS_SRC}/tests/test_builder.h - ${FLATBUFFERS_SRC}/tests/test_assert.cpp - ${FLATBUFFERS_SRC}/tests/test_builder.cpp - ${FLATBUFFERS_SRC}/tests/native_type_test_impl.h - ${FLATBUFFERS_SRC}/tests/native_type_test_impl.cpp -) - add_library( # Sets the name of the library. flatbuffers ${FlatBuffers_Library_SRCS} - ${FlatBuffers_Test_SRCS} ${Generated_SRCS} ) - -add_library( # Sets the name of the library. - flatbuffers_tests - - ${FlatBuffers_Test_SRCS} -) diff --git a/android/app/src/main/java/generated/com/fbs/app/Animal.kt b/android/app/src/main/java/generated/com/fbs/app/Animal.kt index 7654a995c..5564e0396 100644 --- a/android/app/src/main/java/generated/com/fbs/app/Animal.kt +++ b/android/app/src/main/java/generated/com/fbs/app/Animal.kt @@ -57,7 +57,7 @@ class Animal : Table() { return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u } companion object { - fun validateVersion() = Constants.FLATBUFFERS_23_3_3() + fun validateVersion() = Constants.FLATBUFFERS_23_5_26() fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal()) fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal { _bb.order(ByteOrder.LITTLE_ENDIAN) diff --git a/build_defs.bzl b/build_defs.bzl index 5437d7ae0..fff235448 100644 --- a/build_defs.bzl +++ b/build_defs.bzl @@ -87,6 +87,7 @@ def flatbuffer_library_public( optionally a Fileset([reflection_name]) with all generated reflection binaries. """ + reflection_include_paths = include_paths if include_paths == None: include_paths = default_include_paths(flatc_path) include_paths_cmd = ["-I %s" % (s) for s in include_paths] @@ -124,13 +125,16 @@ def flatbuffer_library_public( **kwargs ) if reflection_name: + if reflection_include_paths == None: + reflection_include_paths = default_include_paths(TRUE_FLATC_PATH) + reflection_include_paths_cmd = ["-I %s" % (s) for s in reflection_include_paths] reflection_genrule_cmd = " ".join([ "SRCS=($(SRCS));", "for f in $${SRCS[@]:0:%s}; do" % len(srcs), "$(location %s)" % (TRUE_FLATC_PATH), "-b --schema", " ".join(flatc_args), - " ".join(include_paths_cmd), + " ".join(reflection_include_paths_cmd), language_flag, output_directory, "$$f;", @@ -165,6 +169,7 @@ def flatbuffer_cc_library( name, srcs, srcs_filegroup_name = "", + outs = [], out_prefix = "", deps = [], includes = [], @@ -185,6 +190,7 @@ def flatbuffer_cc_library( srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this filegroup into the `includes` parameter of any other flatbuffer_cc_library that depends on this one's schemas. + outs: Additional outputs expected to be generated by flatc. out_prefix: Prepend this path to the front of all generated files. Usually is a directory name. deps: Optional, list of other flatbuffer_cc_library's to depend on. Cannot be specified @@ -232,7 +238,7 @@ def flatbuffer_cc_library( flatbuffer_library_public( name = srcs_lib, srcs = srcs, - outs = output_headers, + outs = outs + output_headers, language_flag = "-c", out_prefix = out_prefix, includes = includes, diff --git a/dart/lib/flat_buffers.dart b/dart/lib/flat_buffers.dart index 8ce1ab907..6f307872e 100644 --- a/dart/lib/flat_buffers.dart +++ b/dart/lib/flat_buffers.dart @@ -304,7 +304,7 @@ class Builder { assert(_inVTable); // Prepare for writing the VTable. _prepare(_sizeofInt32, 1); - var tableTail = _tail; + final tableTail = _tail; // Prepare the size of the current table. final currentVTable = _currentVTable!; currentVTable.tableSize = tableTail - _currentTableEndTail; @@ -514,7 +514,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setUint32AtTail(tail, tail - value); tail -= _sizeofUint32; } @@ -529,7 +529,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setFloat64AtTail(tail, value); tail -= _sizeofFloat64; } @@ -544,7 +544,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setFloat32AtTail(tail, value); tail -= _sizeofFloat32; } @@ -559,7 +559,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setInt64AtTail(tail, value); tail -= _sizeofInt64; } @@ -574,7 +574,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setUint64AtTail(tail, value); tail -= _sizeofUint64; } @@ -589,7 +589,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setInt32AtTail(tail, value); tail -= _sizeofInt32; } @@ -604,7 +604,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setUint32AtTail(tail, value); tail -= _sizeofUint32; } @@ -619,7 +619,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setInt16AtTail(tail, value); tail -= _sizeofInt16; } @@ -634,7 +634,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setUint16AtTail(tail, value); tail -= _sizeofUint16; } @@ -654,7 +654,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setInt8AtTail(tail, value); tail -= _sizeofUint8; } @@ -669,7 +669,7 @@ class Builder { var tail = _tail; _setUint32AtTail(tail, values.length); tail -= _sizeofUint32; - for (var value in values) { + for (final value in values) { _setUint8AtTail(tail, value); tail -= _sizeofUint8; } @@ -777,17 +777,17 @@ class Builder { _maxAlign = size; } // Prepare amount of required space. - var dataSize = size * count + additionalBytes; - var alignDelta = (-(_tail + dataSize)) & (size - 1); - var bufSize = alignDelta + dataSize; + final dataSize = size * count + additionalBytes; + final alignDelta = (-(_tail + dataSize)) & (size - 1); + final bufSize = alignDelta + dataSize; // Ensure that we have the required amount of space. { - var oldCapacity = _buf.lengthInBytes; + final oldCapacity = _buf.lengthInBytes; if (_tail + bufSize > oldCapacity) { - var desiredNewCapacity = (oldCapacity + bufSize) * 2; + final desiredNewCapacity = (oldCapacity + bufSize) * 2; var deltaCapacity = desiredNewCapacity - oldCapacity; deltaCapacity += (-deltaCapacity) & (_maxAlign - 1); - var newCapacity = oldCapacity + deltaCapacity; + final newCapacity = oldCapacity + deltaCapacity; _buf = _allocator.resize(_buf, newCapacity, _tail, 0); } } @@ -1023,22 +1023,22 @@ abstract class Reader { /// 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) { - var fieldOffset = _vTableFieldOffset(object, offset, field); + final 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) { - var fieldOffset = _vTableFieldOffset(object, offset, field); + final 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) { - var vTableSOffset = object._getInt32(offset); - var vTableOffset = offset - vTableSOffset; - var vTableSize = object._getUint16(vTableOffset); + final vTableSOffset = object._getInt32(offset); + final vTableOffset = offset - vTableSOffset; + final vTableSize = object._getUint16(vTableOffset); if (field >= vTableSize) return 0; return object._getUint16(vTableOffset + field); } @@ -1057,9 +1057,9 @@ class StringReader extends Reader { @override @pragma('vm:prefer-inline') String read(BufferContext bc, int offset) { - var strOffset = bc.derefObject(offset); - var length = bc._getUint32(strOffset); - var bytes = bc._asUint8List(strOffset + _sizeofUint32, length); + final strOffset = bc.derefObject(offset); + final length = bc._getUint32(strOffset); + final bytes = bc._asUint8List(strOffset + _sizeofUint32, length); if (asciiOptimization && _isLatin(bytes)) { return String.fromCharCodes(bytes); } @@ -1068,7 +1068,7 @@ class StringReader extends Reader { @pragma('vm:prefer-inline') static bool _isLatin(Uint8List bytes) { - var length = bytes.length; + final length = bytes.length; for (var i = 0; i < length; i++) { if (bytes[i] > 127) { return false; @@ -1104,7 +1104,7 @@ abstract class TableReader extends Reader { @override T read(BufferContext bc, int offset) { - var objectOffset = bc.derefObject(offset); + final objectOffset = bc.derefObject(offset); return createObject(bc, objectOffset); } } diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml index 8ca66328f..347712caa 100644 --- a/dart/pubspec.yaml +++ b/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: flat_buffers -version: 23.3.3 +version: 23.5.26 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 diff --git a/goldens/README.md b/goldens/README.md new file mode 100644 index 000000000..00bbdc011 --- /dev/null +++ b/goldens/README.md @@ -0,0 +1,26 @@ +# Golden Generated Files + +This directory is a repository for the generated files of `flatc`. + +We check in the generated code so we can see, during a PR review, how the +changes affect the generated output. Its also useful as a reference to point too +as how things work across various languages. + +These files are **NOT** intended to be depended on by any code, such as tests or +or compiled examples. + +## Languages Specifics + +Each language should keep their generated code in their respective directories. +However, the parent schemas can, and should, be shared so we have a consistent +view of things across languages. These are kept in the `schema/` directory. + +Some languages may not support every generation feature, so each language is +required to specify the `flatc` arguments individually. + +* Try to avoid includes and nested directories, preferring it as flat as +possible. + +## Updating + +Just run the `generate_goldens.py` script and it should generate them all. diff --git a/goldens/cpp/basic_generated.h b/goldens/cpp/basic_generated.h new file mode 100644 index 000000000..5d2369603 --- /dev/null +++ b/goldens/cpp/basic_generated.h @@ -0,0 +1,157 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_BASIC_H_ +#define FLATBUFFERS_GENERATED_BASIC_H_ + +#include "flatbuffers/flatbuffers.h" + +// Ensure the included flatbuffers.h is the same version as when this file was +// generated, otherwise it may not be compatible. +static_assert(FLATBUFFERS_VERSION_MAJOR == 23 && + FLATBUFFERS_VERSION_MINOR == 5 && + FLATBUFFERS_VERSION_REVISION == 9, + "Non-compatible flatbuffers version included"); + +struct Galaxy; +struct GalaxyBuilder; + +struct Universe; +struct UniverseBuilder; + +struct Galaxy FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef GalaxyBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NUM_STARS = 4 + }; + int64_t num_stars() const { + return GetField(VT_NUM_STARS, 0); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_NUM_STARS, 8) && + verifier.EndTable(); + } +}; + +struct GalaxyBuilder { + typedef Galaxy Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_num_stars(int64_t num_stars) { + fbb_.AddElement(Galaxy::VT_NUM_STARS, num_stars, 0); + } + explicit GalaxyBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateGalaxy( + ::flatbuffers::FlatBufferBuilder &_fbb, + int64_t num_stars = 0) { + GalaxyBuilder builder_(_fbb); + builder_.add_num_stars(num_stars); + return builder_.Finish(); +} + +struct Universe FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef UniverseBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_AGE = 4, + VT_GALAXIES = 6 + }; + double age() const { + return GetField(VT_AGE, 0.0); + } + const ::flatbuffers::Vector<::flatbuffers::Offset> *galaxies() const { + return GetPointer> *>(VT_GALAXIES); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_AGE, 8) && + VerifyOffset(verifier, VT_GALAXIES) && + verifier.VerifyVector(galaxies()) && + verifier.VerifyVectorOfTables(galaxies()) && + verifier.EndTable(); + } +}; + +struct UniverseBuilder { + typedef Universe Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_age(double age) { + fbb_.AddElement(Universe::VT_AGE, age, 0.0); + } + void add_galaxies(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> galaxies) { + fbb_.AddOffset(Universe::VT_GALAXIES, galaxies); + } + explicit UniverseBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateUniverse( + ::flatbuffers::FlatBufferBuilder &_fbb, + double age = 0.0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> galaxies = 0) { + UniverseBuilder builder_(_fbb); + builder_.add_age(age); + builder_.add_galaxies(galaxies); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateUniverseDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + double age = 0.0, + const std::vector<::flatbuffers::Offset> *galaxies = nullptr) { + auto galaxies__ = galaxies ? _fbb.CreateVector<::flatbuffers::Offset>(*galaxies) : 0; + return CreateUniverse( + _fbb, + age, + galaxies__); +} + +inline const Universe *GetUniverse(const void *buf) { + return ::flatbuffers::GetRoot(buf); +} + +inline const Universe *GetSizePrefixedUniverse(const void *buf) { + return ::flatbuffers::GetSizePrefixedRoot(buf); +} + +inline bool VerifyUniverseBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer(nullptr); +} + +inline bool VerifySizePrefixedUniverseBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer(nullptr); +} + +inline void FinishUniverseBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.Finish(root); +} + +inline void FinishSizePrefixedUniverseBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.FinishSizePrefixed(root); +} + +#endif // FLATBUFFERS_GENERATED_BASIC_H_ diff --git a/goldens/cpp/generate.py b/goldens/cpp/generate.py new file mode 100644 index 000000000..cdc7e8c37 --- /dev/null +++ b/goldens/cpp/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with C++ specifics + flatc_golden(options=["--cpp"] + options, schema=schema, prefix="cpp") + + +def GenerateCpp(): + flatc([], "basic.fbs") diff --git a/goldens/csharp/Galaxy.cs b/goldens/csharp/Galaxy.cs new file mode 100644 index 000000000..7925ce573 --- /dev/null +++ b/goldens/csharp/Galaxy.cs @@ -0,0 +1,45 @@ +// +// automatically generated by the FlatBuffers compiler, do not modify +// + +using global::System; +using global::System.Collections.Generic; +using global::Google.FlatBuffers; + +public struct Galaxy : IFlatbufferObject +{ + private Table __p; + public ByteBuffer ByteBuffer { get { return __p.bb; } } + public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_26(); } + public static Galaxy GetRootAsGalaxy(ByteBuffer _bb) { return GetRootAsGalaxy(_bb, new Galaxy()); } + public static Galaxy GetRootAsGalaxy(ByteBuffer _bb, Galaxy obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } + public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } + public Galaxy __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public long NumStars { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } } + + public static Offset CreateGalaxy(FlatBufferBuilder builder, + long num_stars = 0) { + builder.StartTable(1); + Galaxy.AddNumStars(builder, num_stars); + return Galaxy.EndGalaxy(builder); + } + + public static void StartGalaxy(FlatBufferBuilder builder) { builder.StartTable(1); } + public static void AddNumStars(FlatBufferBuilder builder, long numStars) { builder.AddLong(0, numStars, 0); } + public static Offset EndGalaxy(FlatBufferBuilder builder) { + int o = builder.EndTable(); + return new Offset(o); + } +} + + +static public class GalaxyVerify +{ + static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos) + { + return verifier.VerifyTableStart(tablePos) + && verifier.VerifyField(tablePos, 4 /*NumStars*/, 8 /*long*/, 8, false) + && verifier.VerifyTableEnd(tablePos); + } +} diff --git a/goldens/csharp/Universe.cs b/goldens/csharp/Universe.cs new file mode 100644 index 000000000..16b5b9c87 --- /dev/null +++ b/goldens/csharp/Universe.cs @@ -0,0 +1,59 @@ +// +// automatically generated by the FlatBuffers compiler, do not modify +// + +using global::System; +using global::System.Collections.Generic; +using global::Google.FlatBuffers; + +public struct Universe : IFlatbufferObject +{ + private Table __p; + public ByteBuffer ByteBuffer { get { return __p.bb; } } + public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_26(); } + public static Universe GetRootAsUniverse(ByteBuffer _bb) { return GetRootAsUniverse(_bb, new Universe()); } + public static Universe GetRootAsUniverse(ByteBuffer _bb, Universe obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } + public static bool VerifyUniverse(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, UniverseVerify.Verify); } + public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } + public Universe __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public double Age { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)0.0; } } + public Galaxy? Galaxies(int j) { int o = __p.__offset(6); return o != 0 ? (Galaxy?)(new Galaxy()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; } + public int GalaxiesLength { get { int o = __p.__offset(6); return o != 0 ? __p.__vector_len(o) : 0; } } + + public static Offset CreateUniverse(FlatBufferBuilder builder, + double age = 0.0, + VectorOffset galaxiesOffset = default(VectorOffset)) { + builder.StartTable(2); + Universe.AddAge(builder, age); + Universe.AddGalaxies(builder, galaxiesOffset); + return Universe.EndUniverse(builder); + } + + public static void StartUniverse(FlatBufferBuilder builder) { builder.StartTable(2); } + public static void AddAge(FlatBufferBuilder builder, double age) { builder.AddDouble(0, age, 0.0); } + public static void AddGalaxies(FlatBufferBuilder builder, VectorOffset galaxiesOffset) { builder.AddOffset(1, galaxiesOffset.Value, 0); } + public static VectorOffset CreateGalaxiesVector(FlatBufferBuilder builder, Offset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); } + public static VectorOffset CreateGalaxiesVectorBlock(FlatBufferBuilder builder, Offset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); } + public static VectorOffset CreateGalaxiesVectorBlock(FlatBufferBuilder builder, ArraySegment> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); } + public static VectorOffset CreateGalaxiesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add>(dataPtr, sizeInBytes); return builder.EndVector(); } + public static void StartGalaxiesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); } + public static Offset EndUniverse(FlatBufferBuilder builder) { + int o = builder.EndTable(); + return new Offset(o); + } + public static void FinishUniverseBuffer(FlatBufferBuilder builder, Offset offset) { builder.Finish(offset.Value); } + public static void FinishSizePrefixedUniverseBuffer(FlatBufferBuilder builder, Offset offset) { builder.FinishSizePrefixed(offset.Value); } +} + + +static public class UniverseVerify +{ + static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos) + { + return verifier.VerifyTableStart(tablePos) + && verifier.VerifyField(tablePos, 4 /*Age*/, 8 /*double*/, 8, false) + && verifier.VerifyVectorOfTables(tablePos, 6 /*Galaxies*/, GalaxyVerify.Verify, false) + && verifier.VerifyTableEnd(tablePos); + } +} diff --git a/goldens/csharp/generate.py b/goldens/csharp/generate.py new file mode 100644 index 000000000..86a3a80f5 --- /dev/null +++ b/goldens/csharp/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with C# specifics + flatc_golden(options=["--csharp"] + options, schema=schema, prefix="csharp") + + +def GenerateCSharp(): + flatc([], "basic.fbs") diff --git a/goldens/dart/basic_generated.dart b/goldens/dart/basic_generated.dart new file mode 100644 index 000000000..dabd59601 --- /dev/null +++ b/goldens/dart/basic_generated.dart @@ -0,0 +1,160 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable + +import 'dart:typed_data' show Uint8List; +import 'package:flat_buffers/flat_buffers.dart' as fb; + + +class Galaxy { + Galaxy._(this._bc, this._bcOffset); + factory Galaxy(List bytes) { + final rootRef = fb.BufferContext.fromBytes(bytes); + return reader.read(rootRef, 0); + } + + static const fb.Reader reader = _GalaxyReader(); + + final fb.BufferContext _bc; + final int _bcOffset; + + int get numStars => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 4, 0); + + @override + String toString() { + return 'Galaxy{numStars: ${numStars}}'; + } +} + +class _GalaxyReader extends fb.TableReader { + const _GalaxyReader(); + + @override + Galaxy createObject(fb.BufferContext bc, int offset) => + Galaxy._(bc, offset); +} + +class GalaxyBuilder { + GalaxyBuilder(this.fbBuilder); + + final fb.Builder fbBuilder; + + void begin() { + fbBuilder.startTable(1); + } + + int addNumStars(int? numStars) { + fbBuilder.addInt64(0, numStars); + return fbBuilder.offset; + } + + int finish() { + return fbBuilder.endTable(); + } +} + +class GalaxyObjectBuilder extends fb.ObjectBuilder { + final int? _numStars; + + GalaxyObjectBuilder({ + int? numStars, + }) + : _numStars = numStars; + + /// Finish building, and store into the [fbBuilder]. + @override + int finish(fb.Builder fbBuilder) { + fbBuilder.startTable(1); + fbBuilder.addInt64(0, _numStars); + return fbBuilder.endTable(); + } + + /// Convenience method to serialize to byte list. + @override + Uint8List toBytes([String? fileIdentifier]) { + final fbBuilder = fb.Builder(deduplicateTables: false); + fbBuilder.finish(finish(fbBuilder), fileIdentifier); + return fbBuilder.buffer; + } +} +class Universe { + Universe._(this._bc, this._bcOffset); + factory Universe(List bytes) { + final rootRef = fb.BufferContext.fromBytes(bytes); + return reader.read(rootRef, 0); + } + + static const fb.Reader reader = _UniverseReader(); + + final fb.BufferContext _bc; + final int _bcOffset; + + double get age => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 4, 0.0); + List? get galaxies => const fb.ListReader(Galaxy.reader).vTableGetNullable(_bc, _bcOffset, 6); + + @override + String toString() { + return 'Universe{age: ${age}, galaxies: ${galaxies}}'; + } +} + +class _UniverseReader extends fb.TableReader { + const _UniverseReader(); + + @override + Universe createObject(fb.BufferContext bc, int offset) => + Universe._(bc, offset); +} + +class UniverseBuilder { + UniverseBuilder(this.fbBuilder); + + final fb.Builder fbBuilder; + + void begin() { + fbBuilder.startTable(2); + } + + int addAge(double? age) { + fbBuilder.addFloat64(0, age); + return fbBuilder.offset; + } + int addGalaxiesOffset(int? offset) { + fbBuilder.addOffset(1, offset); + return fbBuilder.offset; + } + + int finish() { + return fbBuilder.endTable(); + } +} + +class UniverseObjectBuilder extends fb.ObjectBuilder { + final double? _age; + final List? _galaxies; + + UniverseObjectBuilder({ + double? age, + List? galaxies, + }) + : _age = age, + _galaxies = galaxies; + + /// Finish building, and store into the [fbBuilder]. + @override + int finish(fb.Builder fbBuilder) { + final int? galaxiesOffset = _galaxies == null ? null + : fbBuilder.writeList(_galaxies!.map((b) => b.getOrCreateOffset(fbBuilder)).toList()); + fbBuilder.startTable(2); + fbBuilder.addFloat64(0, _age); + fbBuilder.addOffset(1, galaxiesOffset); + return fbBuilder.endTable(); + } + + /// Convenience method to serialize to byte list. + @override + Uint8List toBytes([String? fileIdentifier]) { + final fbBuilder = fb.Builder(deduplicateTables: false); + fbBuilder.finish(finish(fbBuilder), fileIdentifier); + return fbBuilder.buffer; + } +} diff --git a/goldens/dart/generate.py b/goldens/dart/generate.py new file mode 100644 index 000000000..a92070c26 --- /dev/null +++ b/goldens/dart/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Dart specifics + flatc_golden(options=["--dart"] + options, schema=schema, prefix="dart") + + +def GenerateDart(): + flatc([], "basic.fbs") diff --git a/goldens/generate_goldens.py b/goldens/generate_goldens.py new file mode 100755 index 000000000..d521b812d --- /dev/null +++ b/goldens/generate_goldens.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +from cpp.generate import GenerateCpp +from csharp.generate import GenerateCSharp +from dart.generate import GenerateDart +from go.generate import GenerateGo +from java.generate import GenerateJava +from kotlin.generate import GenerateKotlin +from lobster.generate import GenerateLobster +from lua.generate import GenerateLua +from nim.generate import GenerateNim +from php.generate import GeneratePhp +from py.generate import GeneratePython +from rust.generate import GenerateRust +from swift.generate import GenerateSwift +from ts.generate import GenerateTs + +# Run each language generation logic +GenerateCpp() +GenerateCSharp() +GenerateDart() +GenerateGo() +GenerateJava() +GenerateKotlin() +GenerateLobster() +GenerateLua() +GenerateNim() +GeneratePhp() +GeneratePython() +GenerateRust() +GenerateSwift() +GenerateTs() diff --git a/goldens/go/Galaxy.go b/goldens/go/Galaxy.go new file mode 100644 index 000000000..870490518 --- /dev/null +++ b/goldens/go/Galaxy.go @@ -0,0 +1,64 @@ +// Code generated by the FlatBuffers compiler. DO NOT EDIT. + +package Galaxy + +import ( + flatbuffers "github.com/google/flatbuffers/go" +) + +type Galaxy struct { + _tab flatbuffers.Table +} + +func GetRootAsGalaxy(buf []byte, offset flatbuffers.UOffsetT) *Galaxy { + n := flatbuffers.GetUOffsetT(buf[offset:]) + x := &Galaxy{} + x.Init(buf, n+offset) + return x +} + +func FinishGalaxyBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) { + builder.Finish(offset) +} + +func GetSizePrefixedRootAsGalaxy(buf []byte, offset flatbuffers.UOffsetT) *Galaxy { + n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:]) + x := &Galaxy{} + x.Init(buf, n+offset+flatbuffers.SizeUint32) + return x +} + +func FinishSizePrefixedGalaxyBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) { + builder.FinishSizePrefixed(offset) +} + +func (rcv *Galaxy) Init(buf []byte, i flatbuffers.UOffsetT) { + rcv._tab.Bytes = buf + rcv._tab.Pos = i +} + +func (rcv *Galaxy) Table() flatbuffers.Table { + return rcv._tab +} + +func (rcv *Galaxy) NumStars() int64 { + o := flatbuffers.UOffsetT(rcv._tab.Offset(4)) + if o != 0 { + return rcv._tab.GetInt64(o + rcv._tab.Pos) + } + return 0 +} + +func (rcv *Galaxy) MutateNumStars(n int64) bool { + return rcv._tab.MutateInt64Slot(4, n) +} + +func GalaxyStart(builder *flatbuffers.Builder) { + builder.StartObject(1) +} +func GalaxyAddNumStars(builder *flatbuffers.Builder, numStars int64) { + builder.PrependInt64Slot(0, numStars, 0) +} +func GalaxyEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { + return builder.EndObject() +} diff --git a/goldens/go/Universe.go b/goldens/go/Universe.go new file mode 100644 index 000000000..0f07f1693 --- /dev/null +++ b/goldens/go/Universe.go @@ -0,0 +1,90 @@ +// Code generated by the FlatBuffers compiler. DO NOT EDIT. + +package Universe + +import ( + flatbuffers "github.com/google/flatbuffers/go" +) + +type Universe struct { + _tab flatbuffers.Table +} + +func GetRootAsUniverse(buf []byte, offset flatbuffers.UOffsetT) *Universe { + n := flatbuffers.GetUOffsetT(buf[offset:]) + x := &Universe{} + x.Init(buf, n+offset) + return x +} + +func FinishUniverseBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) { + builder.Finish(offset) +} + +func GetSizePrefixedRootAsUniverse(buf []byte, offset flatbuffers.UOffsetT) *Universe { + n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:]) + x := &Universe{} + x.Init(buf, n+offset+flatbuffers.SizeUint32) + return x +} + +func FinishSizePrefixedUniverseBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) { + builder.FinishSizePrefixed(offset) +} + +func (rcv *Universe) Init(buf []byte, i flatbuffers.UOffsetT) { + rcv._tab.Bytes = buf + rcv._tab.Pos = i +} + +func (rcv *Universe) Table() flatbuffers.Table { + return rcv._tab +} + +func (rcv *Universe) Age() float64 { + o := flatbuffers.UOffsetT(rcv._tab.Offset(4)) + if o != 0 { + return rcv._tab.GetFloat64(o + rcv._tab.Pos) + } + return 0.0 +} + +func (rcv *Universe) MutateAge(n float64) bool { + return rcv._tab.MutateFloat64Slot(4, n) +} + +func (rcv *Universe) Galaxies(obj *Galaxy, j int) bool { + o := flatbuffers.UOffsetT(rcv._tab.Offset(6)) + if o != 0 { + x := rcv._tab.Vector(o) + x += flatbuffers.UOffsetT(j) * 4 + x = rcv._tab.Indirect(x) + obj.Init(rcv._tab.Bytes, x) + return true + } + return false +} + +func (rcv *Universe) GalaxiesLength() int { + o := flatbuffers.UOffsetT(rcv._tab.Offset(6)) + if o != 0 { + return rcv._tab.VectorLen(o) + } + return 0 +} + +func UniverseStart(builder *flatbuffers.Builder) { + builder.StartObject(2) +} +func UniverseAddAge(builder *flatbuffers.Builder, age float64) { + builder.PrependFloat64Slot(0, age, 0.0) +} +func UniverseAddGalaxies(builder *flatbuffers.Builder, galaxies flatbuffers.UOffsetT) { + builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(galaxies), 0) +} +func UniverseStartGalaxiesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { + return builder.StartVector(4, numElems, 4) +} +func UniverseEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { + return builder.EndObject() +} diff --git a/goldens/go/generate.py b/goldens/go/generate.py new file mode 100644 index 000000000..358c42c30 --- /dev/null +++ b/goldens/go/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Go specifics + flatc_golden(options=["--go"] + options, schema=schema, prefix="go") + + +def GenerateGo(): + flatc([], "basic.fbs") diff --git a/goldens/golden_utils.py b/goldens/golden_utils.py new file mode 100644 index 000000000..d2aab1330 --- /dev/null +++ b/goldens/golden_utils.py @@ -0,0 +1,30 @@ +import sys +from pathlib import Path + +# Get the path where this script is located so we can invoke the script from +# any directory and have the paths work correctly. +script_path = Path(__file__).parent.resolve() + +# Get the root path as an absolute path, so all derived paths are absolute. +root_path = script_path.parent.absolute() + +# Get the location of the schema +schema_path = Path(script_path, "schema") + +# Too add the util package in /scripts/util.py +sys.path.append(str(root_path.absolute())) + +from scripts.util import flatc + + +def flatc_golden(options, schema, prefix): + # wrap the generic flatc call with specifis for these goldens. + flatc( + options=options, + # where the files are generated, typically the language (e.g. "cpp"). + prefix=prefix, + # The schema are relative to the schema directory. + schema=str(Path(schema_path, schema)), + # Run flatc from this location. + cwd=script_path, + ) diff --git a/goldens/java/Galaxy.java b/goldens/java/Galaxy.java new file mode 100644 index 000000000..bcf139f3d --- /dev/null +++ b/goldens/java/Galaxy.java @@ -0,0 +1,51 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import com.google.flatbuffers.BaseVector; +import com.google.flatbuffers.BooleanVector; +import com.google.flatbuffers.ByteVector; +import com.google.flatbuffers.Constants; +import com.google.flatbuffers.DoubleVector; +import com.google.flatbuffers.FlatBufferBuilder; +import com.google.flatbuffers.FloatVector; +import com.google.flatbuffers.IntVector; +import com.google.flatbuffers.LongVector; +import com.google.flatbuffers.ShortVector; +import com.google.flatbuffers.StringVector; +import com.google.flatbuffers.Struct; +import com.google.flatbuffers.Table; +import com.google.flatbuffers.UnionVector; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +@SuppressWarnings("unused") +public final class Galaxy extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); } + public static Galaxy getRootAsGalaxy(ByteBuffer _bb) { return getRootAsGalaxy(_bb, new Galaxy()); } + public static Galaxy getRootAsGalaxy(ByteBuffer _bb, Galaxy obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } + public Galaxy __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public long numStars() { int o = __offset(4); return o != 0 ? bb.getLong(o + bb_pos) : 0L; } + + public static int createGalaxy(FlatBufferBuilder builder, + long numStars) { + builder.startTable(1); + Galaxy.addNumStars(builder, numStars); + return Galaxy.endGalaxy(builder); + } + + public static void startGalaxy(FlatBufferBuilder builder) { builder.startTable(1); } + public static void addNumStars(FlatBufferBuilder builder, long numStars) { builder.addLong(0, numStars, 0L); } + public static int endGalaxy(FlatBufferBuilder builder) { + int o = builder.endTable(); + return o; + } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public Galaxy get(int j) { return get(new Galaxy(), j); } + public Galaxy get(Galaxy obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } +} + diff --git a/goldens/java/Universe.java b/goldens/java/Universe.java new file mode 100644 index 000000000..400c91a69 --- /dev/null +++ b/goldens/java/Universe.java @@ -0,0 +1,63 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import com.google.flatbuffers.BaseVector; +import com.google.flatbuffers.BooleanVector; +import com.google.flatbuffers.ByteVector; +import com.google.flatbuffers.Constants; +import com.google.flatbuffers.DoubleVector; +import com.google.flatbuffers.FlatBufferBuilder; +import com.google.flatbuffers.FloatVector; +import com.google.flatbuffers.IntVector; +import com.google.flatbuffers.LongVector; +import com.google.flatbuffers.ShortVector; +import com.google.flatbuffers.StringVector; +import com.google.flatbuffers.Struct; +import com.google.flatbuffers.Table; +import com.google.flatbuffers.UnionVector; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +@SuppressWarnings("unused") +public final class Universe extends Table { + public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); } + public static Universe getRootAsUniverse(ByteBuffer _bb) { return getRootAsUniverse(_bb, new Universe()); } + public static Universe getRootAsUniverse(ByteBuffer _bb, Universe obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } + public Universe __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public double age() { int o = __offset(4); return o != 0 ? bb.getDouble(o + bb_pos) : 0.0; } + public Galaxy galaxies(int j) { return galaxies(new Galaxy(), j); } + public Galaxy galaxies(Galaxy obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; } + public int galaxiesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; } + public Galaxy.Vector galaxiesVector() { return galaxiesVector(new Galaxy.Vector()); } + public Galaxy.Vector galaxiesVector(Galaxy.Vector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; } + + public static int createUniverse(FlatBufferBuilder builder, + double age, + int galaxiesOffset) { + builder.startTable(2); + Universe.addAge(builder, age); + Universe.addGalaxies(builder, galaxiesOffset); + return Universe.endUniverse(builder); + } + + public static void startUniverse(FlatBufferBuilder builder) { builder.startTable(2); } + public static void addAge(FlatBufferBuilder builder, double age) { builder.addDouble(0, age, 0.0); } + public static void addGalaxies(FlatBufferBuilder builder, int galaxiesOffset) { builder.addOffset(1, galaxiesOffset, 0); } + public static int createGalaxiesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); } + public static void startGalaxiesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } + public static int endUniverse(FlatBufferBuilder builder) { + int o = builder.endTable(); + return o; + } + public static void finishUniverseBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset); } + public static void finishSizePrefixedUniverseBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset); } + + public static final class Vector extends BaseVector { + public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } + + public Universe get(int j) { return get(new Universe(), j); } + public Universe get(Universe obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } + } +} + diff --git a/goldens/java/generate.py b/goldens/java/generate.py new file mode 100644 index 000000000..cc1a8b294 --- /dev/null +++ b/goldens/java/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Java specifics + flatc_golden(options=["--java"] + options, schema=schema, prefix="java") + + +def GenerateJava(): + flatc([], "basic.fbs") diff --git a/goldens/kotlin/Galaxy.kt b/goldens/kotlin/Galaxy.kt new file mode 100644 index 000000000..5f2228d84 --- /dev/null +++ b/goldens/kotlin/Galaxy.kt @@ -0,0 +1,53 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import com.google.flatbuffers.BaseVector +import com.google.flatbuffers.BooleanVector +import com.google.flatbuffers.ByteVector +import com.google.flatbuffers.Constants +import com.google.flatbuffers.DoubleVector +import com.google.flatbuffers.FlatBufferBuilder +import com.google.flatbuffers.FloatVector +import com.google.flatbuffers.LongVector +import com.google.flatbuffers.StringVector +import com.google.flatbuffers.Struct +import com.google.flatbuffers.Table +import com.google.flatbuffers.UnionVector +import java.nio.ByteBuffer +import java.nio.ByteOrder +import kotlin.math.sign + +@Suppress("unused") +class Galaxy : Table() { + + fun __init(_i: Int, _bb: ByteBuffer) { + __reset(_i, _bb) + } + fun __assign(_i: Int, _bb: ByteBuffer) : Galaxy { + __init(_i, _bb) + return this + } + val numStars : Long + get() { + val o = __offset(4) + return if(o != 0) bb.getLong(o + bb_pos) else 0L + } + companion object { + fun validateVersion() = Constants.FLATBUFFERS_23_5_26() + fun getRootAsGalaxy(_bb: ByteBuffer): Galaxy = getRootAsGalaxy(_bb, Galaxy()) + fun getRootAsGalaxy(_bb: ByteBuffer, obj: Galaxy): Galaxy { + _bb.order(ByteOrder.LITTLE_ENDIAN) + return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)) + } + fun createGalaxy(builder: FlatBufferBuilder, numStars: Long) : Int { + builder.startTable(1) + addNumStars(builder, numStars) + return endGalaxy(builder) + } + fun startGalaxy(builder: FlatBufferBuilder) = builder.startTable(1) + fun addNumStars(builder: FlatBufferBuilder, numStars: Long) = builder.addLong(0, numStars, 0L) + fun endGalaxy(builder: FlatBufferBuilder) : Int { + val o = builder.endTable() + return o + } + } +} diff --git a/goldens/kotlin/Universe.kt b/goldens/kotlin/Universe.kt new file mode 100644 index 000000000..343817179 --- /dev/null +++ b/goldens/kotlin/Universe.kt @@ -0,0 +1,78 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import com.google.flatbuffers.BaseVector +import com.google.flatbuffers.BooleanVector +import com.google.flatbuffers.ByteVector +import com.google.flatbuffers.Constants +import com.google.flatbuffers.DoubleVector +import com.google.flatbuffers.FlatBufferBuilder +import com.google.flatbuffers.FloatVector +import com.google.flatbuffers.LongVector +import com.google.flatbuffers.StringVector +import com.google.flatbuffers.Struct +import com.google.flatbuffers.Table +import com.google.flatbuffers.UnionVector +import java.nio.ByteBuffer +import java.nio.ByteOrder +import kotlin.math.sign + +@Suppress("unused") +class Universe : Table() { + + fun __init(_i: Int, _bb: ByteBuffer) { + __reset(_i, _bb) + } + fun __assign(_i: Int, _bb: ByteBuffer) : Universe { + __init(_i, _bb) + return this + } + val age : Double + get() { + val o = __offset(4) + return if(o != 0) bb.getDouble(o + bb_pos) else 0.0 + } + fun galaxies(j: Int) : Galaxy? = galaxies(Galaxy(), j) + fun galaxies(obj: Galaxy, j: Int) : Galaxy? { + val o = __offset(6) + return if (o != 0) { + obj.__assign(__indirect(__vector(o) + j * 4), bb) + } else { + null + } + } + val galaxiesLength : Int + get() { + val o = __offset(6); return if (o != 0) __vector_len(o) else 0 + } + companion object { + fun validateVersion() = Constants.FLATBUFFERS_23_5_26() + fun getRootAsUniverse(_bb: ByteBuffer): Universe = getRootAsUniverse(_bb, Universe()) + fun getRootAsUniverse(_bb: ByteBuffer, obj: Universe): Universe { + _bb.order(ByteOrder.LITTLE_ENDIAN) + return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)) + } + fun createUniverse(builder: FlatBufferBuilder, age: Double, galaxiesOffset: Int) : Int { + builder.startTable(2) + addAge(builder, age) + addGalaxies(builder, galaxiesOffset) + return endUniverse(builder) + } + fun startUniverse(builder: FlatBufferBuilder) = builder.startTable(2) + fun addAge(builder: FlatBufferBuilder, age: Double) = builder.addDouble(0, age, 0.0) + fun addGalaxies(builder: FlatBufferBuilder, galaxies: Int) = builder.addOffset(1, galaxies, 0) + fun createGalaxiesVector(builder: FlatBufferBuilder, data: IntArray) : Int { + builder.startVector(4, data.size, 4) + for (i in data.size - 1 downTo 0) { + builder.addOffset(data[i]) + } + return builder.endVector() + } + fun startGalaxiesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4) + fun endUniverse(builder: FlatBufferBuilder) : Int { + val o = builder.endTable() + return o + } + fun finishUniverseBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset) + fun finishSizePrefixedUniverseBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset) + } +} diff --git a/goldens/kotlin/generate.py b/goldens/kotlin/generate.py new file mode 100644 index 000000000..ac8b55174 --- /dev/null +++ b/goldens/kotlin/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Kotlin specifics + flatc_golden(options=["--kotlin"] + options, schema=schema, prefix="kotlin") + + +def GenerateKotlin(): + flatc([], "basic.fbs") diff --git a/goldens/lobster/basic_generated.lobster b/goldens/lobster/basic_generated.lobster new file mode 100644 index 000000000..5d4fd25b8 --- /dev/null +++ b/goldens/lobster/basic_generated.lobster @@ -0,0 +1,55 @@ +// automatically generated by the FlatBuffers compiler, do not modify +import flatbuffers + +class Galaxy + +class Universe + +class Galaxy : flatbuffers_handle + def num_stars() -> int: + return buf_.flatbuffers_field_int64(pos_, 4, 0) + +def GetRootAsGalaxy(buf:string): return Galaxy { buf, buf.flatbuffers_indirect(0) } + +struct GalaxyBuilder: + b_:flatbuffers_builder + def start(): + b_.StartObject(1) + return this + def add_num_stars(num_stars:int): + b_.PrependInt64Slot(0, num_stars, 0) + return this + def end(): + return b_.EndObject() + +class Universe : flatbuffers_handle + def age() -> float: + return buf_.flatbuffers_field_float64(pos_, 4, 0.0) + def galaxies(i:int) -> Galaxy: + return Galaxy { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 6) + i * 4) } + def galaxies_length() -> int: + return buf_.flatbuffers_field_vector_len(pos_, 6) + +def GetRootAsUniverse(buf:string): return Universe { buf, buf.flatbuffers_indirect(0) } + +struct UniverseBuilder: + b_:flatbuffers_builder + def start(): + b_.StartObject(2) + return this + def add_age(age:float): + b_.PrependFloat64Slot(0, age, 0.0) + return this + def add_galaxies(galaxies:flatbuffers_offset): + b_.PrependUOffsetTRelativeSlot(1, galaxies) + return this + def end(): + return b_.EndObject() + +def UniverseStartGalaxiesVector(b_:flatbuffers_builder, n_:int): + b_.StartVector(4, n_, 4) +def UniverseCreateGalaxiesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]): + b_.StartVector(4, v_.length, 4) + reverse(v_) e_: b_.PrependUOffsetTRelative(e_) + return b_.EndVector(v_.length) + diff --git a/goldens/lobster/generate.py b/goldens/lobster/generate.py new file mode 100644 index 000000000..cb75fda4b --- /dev/null +++ b/goldens/lobster/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Lobster specifics + flatc_golden(options=["--lobster"] + options, schema=schema, prefix="lobster") + + +def GenerateLobster(): + flatc([], "basic.fbs") diff --git a/goldens/lua/Galaxy.lua b/goldens/lua/Galaxy.lua new file mode 100644 index 000000000..071a1c80a --- /dev/null +++ b/goldens/lua/Galaxy.lua @@ -0,0 +1,48 @@ +--[[ Galaxy + + Automatically generated by the FlatBuffers compiler, do not modify. + Or modify. I'm a message, not a cop. + + flatc version: 23.5.9 + + Declared by : //basic.fbs + Rooting type : Universe (//basic.fbs) + +--]] + +local flatbuffers = require('flatbuffers') + +local Galaxy = {} +local mt = {} + +function Galaxy.New() + local o = {} + setmetatable(o, {__index = mt}) + return o +end + +function mt:Init(buf, pos) + self.view = flatbuffers.view.New(buf, pos) +end + +function mt:NumStars() + local o = self.view:Offset(4) + if o ~= 0 then + return self.view:Get(flatbuffers.N.Int64, self.view.pos + o) + end + return 0 +end + +function Galaxy.Start(builder) + builder:StartObject(1) +end + +function Galaxy.AddNumStars(builder, numStars) + builder:PrependInt64Slot(0, numStars, 0) +end + +function Galaxy.End(builder) + return builder:EndObject() +end + +return Galaxy \ No newline at end of file diff --git a/goldens/lua/Universe.lua b/goldens/lua/Universe.lua new file mode 100644 index 000000000..d7ef085eb --- /dev/null +++ b/goldens/lua/Universe.lua @@ -0,0 +1,88 @@ +--[[ Universe + + Automatically generated by the FlatBuffers compiler, do not modify. + Or modify. I'm a message, not a cop. + + flatc version: 23.5.9 + + Declared by : //basic.fbs + Rooting type : Universe (//basic.fbs) + +--]] + +local __Galaxy = require('Galaxy') +local flatbuffers = require('flatbuffers') + +local Universe = {} +local mt = {} + +function Universe.New() + local o = {} + setmetatable(o, {__index = mt}) + return o +end + +function Universe.GetRootAsUniverse(buf, offset) + if type(buf) == "string" then + buf = flatbuffers.binaryArray.New(buf) + end + + local n = flatbuffers.N.UOffsetT:Unpack(buf, offset) + local o = Universe.New() + o:Init(buf, n + offset) + return o +end + +function mt:Init(buf, pos) + self.view = flatbuffers.view.New(buf, pos) +end + +function mt:Age() + local o = self.view:Offset(4) + if o ~= 0 then + return self.view:Get(flatbuffers.N.Float64, self.view.pos + o) + end + return 0.0 +end + +function mt:Galaxies(j) + local o = self.view:Offset(6) + if o ~= 0 then + local x = self.view:Vector(o) + x = x + ((j-1) * 4) + x = self.view:Indirect(x) + local obj = __Galaxy.New() + obj:Init(self.view.bytes, x) + return obj + end +end + +function mt:GalaxiesLength() + local o = self.view:Offset(6) + if o ~= 0 then + return self.view:VectorLen(o) + end + return 0 +end + +function Universe.Start(builder) + builder:StartObject(2) +end + +function Universe.AddAge(builder, age) + builder:PrependFloat64Slot(0, age, 0.0) +end + +function Universe.AddGalaxies(builder, galaxies) + builder:PrependUOffsetTRelativeSlot(1, galaxies, 0) +end + +function Universe.StartGalaxiesVector(builder, numElems) + return builder:StartVector(4, numElems, 4) +end + +function Universe.End(builder) + return builder:EndObject() +end + +return Universe \ No newline at end of file diff --git a/goldens/lua/generate.py b/goldens/lua/generate.py new file mode 100644 index 000000000..d099118a8 --- /dev/null +++ b/goldens/lua/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Lua specifics + flatc_golden(options=["--lua"] + options, schema=schema, prefix="lua") + + +def GenerateLua(): + flatc([], "basic.fbs") diff --git a/goldens/nim/Galaxy.nim b/goldens/nim/Galaxy.nim new file mode 100644 index 000000000..7728c3677 --- /dev/null +++ b/goldens/nim/Galaxy.nim @@ -0,0 +1,26 @@ +#[ Galaxy + Automatically generated by the FlatBuffers compiler, do not modify. + Or modify. I'm a message, not a cop. + + flatc version: 23.5.9 + + Declared by : //basic.fbs + Rooting type : Universe (//basic.fbs) +]# + +import flatbuffers + +type Galaxy* = object of FlatObj +func numStars*(self: Galaxy): int64 = + let o = self.tab.Offset(4) + if o != 0: + return Get[int64](self.tab, self.tab.Pos + o) + return 0 +func `numStars=`*(self: var Galaxy, n: int64): bool = + return self.tab.MutateSlot(4, n) +proc GalaxyStart*(builder: var Builder) = + builder.StartObject(1) +proc GalaxyAddnumStars*(builder: var Builder, numStars: int64) = + builder.PrependSlot(0, numStars, default(int64)) +proc GalaxyEnd*(builder: var Builder): uoffset = + return builder.EndObject() diff --git a/goldens/nim/Universe.nim b/goldens/nim/Universe.nim new file mode 100644 index 000000000..3a4e43d2b --- /dev/null +++ b/goldens/nim/Universe.nim @@ -0,0 +1,46 @@ +#[ Universe + Automatically generated by the FlatBuffers compiler, do not modify. + Or modify. I'm a message, not a cop. + + flatc version: 23.5.9 + + Declared by : //basic.fbs + Rooting type : Universe (//basic.fbs) +]# + +import Galaxy as Galaxy +import flatbuffers +import std/options + +type Universe* = object of FlatObj +func age*(self: Universe): float64 = + let o = self.tab.Offset(4) + if o != 0: + return Get[float64](self.tab, self.tab.Pos + o) + return 0.0 +func `age=`*(self: var Universe, n: float64): bool = + return self.tab.MutateSlot(4, n) +func galaxiesLength*(self: Universe): int = + let o = self.tab.Offset(6) + if o != 0: + return self.tab.VectorLen(o) +func galaxies*(self: Universe, j: int): Galaxy.Galaxy = + let o = self.tab.Offset(6) + if o != 0: + var x = self.tab.Vector(o) + x += j.uoffset * 4.uoffset + return Galaxy.Galaxy(tab: Vtable(Bytes: self.tab.Bytes, Pos: x)) +func galaxies*(self: Universe): seq[Galaxy.Galaxy] = + let len = self.galaxiesLength + for i in countup(0, len - 1): + result.add(self.galaxies(i)) +proc UniverseStart*(builder: var Builder) = + builder.StartObject(2) +proc UniverseAddage*(builder: var Builder, age: float64) = + builder.PrependSlot(0, age, default(float64)) +proc UniverseAddgalaxies*(builder: var Builder, galaxies: uoffset) = + builder.PrependSlot(1, galaxies, default(uoffset)) +proc UniverseStartgalaxiesVector*(builder: var Builder, numElems: uoffset) = + builder.StartVector(4, numElems, 4) +proc UniverseEnd*(builder: var Builder): uoffset = + return builder.EndObject() diff --git a/goldens/nim/generate.py b/goldens/nim/generate.py new file mode 100644 index 000000000..16c0d3bcd --- /dev/null +++ b/goldens/nim/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Nim specifics + flatc_golden(options=["--nim"] + options, schema=schema, prefix="nim") + + +def GenerateNim(): + flatc([], "basic.fbs") diff --git a/goldens/php/Galaxy.php b/goldens/php/Galaxy.php new file mode 100644 index 000000000..256a72e4b --- /dev/null +++ b/goldens/php/Galaxy.php @@ -0,0 +1,82 @@ +init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb)); + } + + /** + * @param int $_i offset + * @param ByteBuffer $_bb + * @return Galaxy + **/ + public function init($_i, ByteBuffer $_bb) + { + $this->bb_pos = $_i; + $this->bb = $_bb; + return $this; + } + + /** + * @return long + */ + public function getNumStars() + { + $o = $this->__offset(4); + return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0; + } + + /** + * @param FlatBufferBuilder $builder + * @return void + */ + public static function startGalaxy(FlatBufferBuilder $builder) + { + $builder->StartObject(1); + } + + /** + * @param FlatBufferBuilder $builder + * @return Galaxy + */ + public static function createGalaxy(FlatBufferBuilder $builder, $num_stars) + { + $builder->startObject(1); + self::addNumStars($builder, $num_stars); + $o = $builder->endObject(); + return $o; + } + + /** + * @param FlatBufferBuilder $builder + * @param long + * @return void + */ + public static function addNumStars(FlatBufferBuilder $builder, $numStars) + { + $builder->addLongX(0, $numStars, 0); + } + + /** + * @param FlatBufferBuilder $builder + * @return int table offset + */ + public static function endGalaxy(FlatBufferBuilder $builder) + { + $o = $builder->endObject(); + return $o; + } +} diff --git a/goldens/php/Universe.php b/goldens/php/Universe.php new file mode 100644 index 000000000..ea98096b6 --- /dev/null +++ b/goldens/php/Universe.php @@ -0,0 +1,141 @@ +init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb)); + } + + /** + * @param int $_i offset + * @param ByteBuffer $_bb + * @return Universe + **/ + public function init($_i, ByteBuffer $_bb) + { + $this->bb_pos = $_i; + $this->bb = $_bb; + return $this; + } + + /** + * @return double + */ + public function getAge() + { + $o = $this->__offset(4); + return $o != 0 ? $this->bb->getDouble($o + $this->bb_pos) : 0.0; + } + + /** + * @returnVectorOffset + */ + public function getGalaxies($j) + { + $o = $this->__offset(6); + $obj = new Galaxy(); + return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null; + } + + /** + * @return int + */ + public function getGalaxiesLength() + { + $o = $this->__offset(6); + return $o != 0 ? $this->__vector_len($o) : 0; + } + + /** + * @param FlatBufferBuilder $builder + * @return void + */ + public static function startUniverse(FlatBufferBuilder $builder) + { + $builder->StartObject(2); + } + + /** + * @param FlatBufferBuilder $builder + * @return Universe + */ + public static function createUniverse(FlatBufferBuilder $builder, $age, $galaxies) + { + $builder->startObject(2); + self::addAge($builder, $age); + self::addGalaxies($builder, $galaxies); + $o = $builder->endObject(); + return $o; + } + + /** + * @param FlatBufferBuilder $builder + * @param double + * @return void + */ + public static function addAge(FlatBufferBuilder $builder, $age) + { + $builder->addDoubleX(0, $age, 0.0); + } + + /** + * @param FlatBufferBuilder $builder + * @param VectorOffset + * @return void + */ + public static function addGalaxies(FlatBufferBuilder $builder, $galaxies) + { + $builder->addOffsetX(1, $galaxies, 0); + } + + /** + * @param FlatBufferBuilder $builder + * @param array offset array + * @return int vector offset + */ + public static function createGalaxiesVector(FlatBufferBuilder $builder, array $data) + { + $builder->startVector(4, count($data), 4); + for ($i = count($data) - 1; $i >= 0; $i--) { + $builder->putOffset($data[$i]); + } + return $builder->endVector(); + } + + /** + * @param FlatBufferBuilder $builder + * @param int $numElems + * @return void + */ + public static function startGalaxiesVector(FlatBufferBuilder $builder, $numElems) + { + $builder->startVector(4, $numElems, 4); + } + + /** + * @param FlatBufferBuilder $builder + * @return int table offset + */ + public static function endUniverse(FlatBufferBuilder $builder) + { + $o = $builder->endObject(); + return $o; + } + + public static function finishUniverseBuffer(FlatBufferBuilder $builder, $offset) + { + $builder->finish($offset); + } +} diff --git a/goldens/php/generate.py b/goldens/php/generate.py new file mode 100644 index 000000000..6e9144c67 --- /dev/null +++ b/goldens/php/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with PHP specifics + flatc_golden(options=["--php"] + options, schema=schema, prefix="php") + + +def GeneratePhp(): + flatc([], "basic.fbs") diff --git a/goldens/py/Galaxy.py b/goldens/py/Galaxy.py new file mode 100644 index 000000000..4b28f68a9 --- /dev/null +++ b/goldens/py/Galaxy.py @@ -0,0 +1,50 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: + +import flatbuffers +from flatbuffers.compat import import_numpy +np = import_numpy() + +class Galaxy(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAs(cls, buf, offset=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = Galaxy() + x.Init(buf, n + offset) + return x + + @classmethod + def GetRootAsGalaxy(cls, buf, offset=0): + """This method is deprecated. Please switch to GetRootAs.""" + return cls.GetRootAs(buf, offset) + # Galaxy + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # Galaxy + def NumStars(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos) + return 0 + +def GalaxyStart(builder): + builder.StartObject(1) + +def Start(builder): + GalaxyStart(builder) + +def GalaxyAddNumStars(builder, numStars): + builder.PrependInt64Slot(0, numStars, 0) + +def AddNumStars(builder: flatbuffers.Builder, numStars: int): + GalaxyAddNumStars(builder, numStars) + +def GalaxyEnd(builder): + return builder.EndObject() + +def End(builder): + return GalaxyEnd(builder) diff --git a/goldens/py/Universe.py b/goldens/py/Universe.py new file mode 100644 index 000000000..fa0044c50 --- /dev/null +++ b/goldens/py/Universe.py @@ -0,0 +1,87 @@ +# automatically generated by the FlatBuffers compiler, do not modify + +# namespace: + +import flatbuffers +from flatbuffers.compat import import_numpy +np = import_numpy() + +class Universe(object): + __slots__ = ['_tab'] + + @classmethod + def GetRootAs(cls, buf, offset=0): + n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset) + x = Universe() + x.Init(buf, n + offset) + return x + + @classmethod + def GetRootAsUniverse(cls, buf, offset=0): + """This method is deprecated. Please switch to GetRootAs.""" + return cls.GetRootAs(buf, offset) + # Universe + def Init(self, buf, pos): + self._tab = flatbuffers.table.Table(buf, pos) + + # Universe + def Age(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) + if o != 0: + return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos) + return 0.0 + + # Universe + def Galaxies(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 .Galaxy import Galaxy + obj = Galaxy() + obj.Init(self._tab.Bytes, x) + return obj + return None + + # Universe + def GalaxiesLength(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) + if o != 0: + return self._tab.VectorLen(o) + return 0 + + # Universe + def GalaxiesIsNone(self): + o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) + return o == 0 + +def UniverseStart(builder): + builder.StartObject(2) + +def Start(builder): + UniverseStart(builder) + +def UniverseAddAge(builder, age): + builder.PrependFloat64Slot(0, age, 0.0) + +def AddAge(builder: flatbuffers.Builder, age: float): + UniverseAddAge(builder, age) + +def UniverseAddGalaxies(builder, galaxies): + builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(galaxies), 0) + +def AddGalaxies(builder: flatbuffers.Builder, galaxies: int): + UniverseAddGalaxies(builder, galaxies) + +def UniverseStartGalaxiesVector(builder, numElems): + return builder.StartVector(4, numElems, 4) + +def StartGalaxiesVector(builder, numElems: int) -> int: + return UniverseStartGalaxiesVector(builder, numElems) + +def UniverseEnd(builder): + return builder.EndObject() + +def End(builder): + return UniverseEnd(builder) diff --git a/goldens/py/__init__.py b/goldens/py/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/goldens/py/generate.py b/goldens/py/generate.py new file mode 100644 index 000000000..ceff5d2d6 --- /dev/null +++ b/goldens/py/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Python specifics + flatc_golden(options=["--python"] + options, schema=schema, prefix="py") + + +def GeneratePython(): + flatc([], "basic.fbs") diff --git a/goldens/rust/basic_generated.rs b/goldens/rust/basic_generated.rs new file mode 100644 index 000000000..f755a5fe7 --- /dev/null +++ b/goldens/rust/basic_generated.rs @@ -0,0 +1,293 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +// @generated + +use core::mem; +use core::cmp::Ordering; + +extern crate flatbuffers; +use self::flatbuffers::{EndianScalar, Follow}; + +pub enum GalaxyOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct Galaxy<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for Galaxy<'a> { + type Inner = Galaxy<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> Galaxy<'a> { + pub const VT_NUM_STARS: flatbuffers::VOffsetT = 4; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + Galaxy { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args GalaxyArgs + ) -> flatbuffers::WIPOffset> { + let mut builder = GalaxyBuilder::new(_fbb); + builder.add_num_stars(args.num_stars); + builder.finish() + } + + + #[inline] + pub fn num_stars(&self) -> i64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Galaxy::VT_NUM_STARS, Some(0)).unwrap()} + } +} + +impl flatbuffers::Verifiable for Galaxy<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::("num_stars", Self::VT_NUM_STARS, false)? + .finish(); + Ok(()) + } +} +pub struct GalaxyArgs { + pub num_stars: i64, +} +impl<'a> Default for GalaxyArgs { + #[inline] + fn default() -> Self { + GalaxyArgs { + num_stars: 0, + } + } +} + +pub struct GalaxyBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b> GalaxyBuilder<'a, 'b> { + #[inline] + pub fn add_num_stars(&mut self, num_stars: i64) { + self.fbb_.push_slot::(Galaxy::VT_NUM_STARS, num_stars, 0); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> GalaxyBuilder<'a, 'b> { + let start = _fbb.start_table(); + GalaxyBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for Galaxy<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("Galaxy"); + ds.field("num_stars", &self.num_stars()); + ds.finish() + } +} +pub enum UniverseOffset {} +#[derive(Copy, Clone, PartialEq)] + +pub struct Universe<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for Universe<'a> { + type Inner = Universe<'a>; + #[inline] + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } + } +} + +impl<'a> Universe<'a> { + pub const VT_AGE: flatbuffers::VOffsetT = 4; + pub const VT_GALAXIES: flatbuffers::VOffsetT = 6; + + #[inline] + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + Universe { _tab: table } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args UniverseArgs<'args> + ) -> flatbuffers::WIPOffset> { + let mut builder = UniverseBuilder::new(_fbb); + builder.add_age(args.age); + if let Some(x) = args.galaxies { builder.add_galaxies(x); } + builder.finish() + } + + + #[inline] + pub fn age(&self) -> f64 { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Universe::VT_AGE, Some(0.0)).unwrap()} + } + #[inline] + pub fn galaxies(&self) -> Option>>> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>>(Universe::VT_GALAXIES, None)} + } +} + +impl flatbuffers::Verifiable for Universe<'_> { + #[inline] + fn run_verifier( + v: &mut flatbuffers::Verifier, pos: usize + ) -> Result<(), flatbuffers::InvalidFlatbuffer> { + use self::flatbuffers::Verifiable; + v.visit_table(pos)? + .visit_field::("age", Self::VT_AGE, false)? + .visit_field::>>>("galaxies", Self::VT_GALAXIES, false)? + .finish(); + Ok(()) + } +} +pub struct UniverseArgs<'a> { + pub age: f64, + pub galaxies: Option>>>>, +} +impl<'a> Default for UniverseArgs<'a> { + #[inline] + fn default() -> Self { + UniverseArgs { + age: 0.0, + galaxies: None, + } + } +} + +pub struct UniverseBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b> UniverseBuilder<'a, 'b> { + #[inline] + pub fn add_age(&mut self, age: f64) { + self.fbb_.push_slot::(Universe::VT_AGE, age, 0.0); + } + #[inline] + pub fn add_galaxies(&mut self, galaxies: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(Universe::VT_GALAXIES, galaxies); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> UniverseBuilder<'a, 'b> { + let start = _fbb.start_table(); + UniverseBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + +impl core::fmt::Debug for Universe<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("Universe"); + ds.field("age", &self.age()); + ds.field("galaxies", &self.galaxies()); + ds.finish() + } +} +#[inline] +/// Verifies that a buffer of bytes contains a `Universe` +/// and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_universe_unchecked`. +pub fn root_as_universe(buf: &[u8]) -> Result { + flatbuffers::root::(buf) +} +#[inline] +/// Verifies that a buffer of bytes contains a size prefixed +/// `Universe` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `size_prefixed_root_as_universe_unchecked`. +pub fn size_prefixed_root_as_universe(buf: &[u8]) -> Result { + flatbuffers::size_prefixed_root::(buf) +} +#[inline] +/// Verifies, with the given options, that a buffer of bytes +/// contains a `Universe` and returns it. +/// Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_universe_unchecked`. +pub fn root_as_universe_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::root_with_opts::>(opts, buf) +} +#[inline] +/// Verifies, with the given verifier options, that a buffer of +/// bytes contains a size prefixed `Universe` and returns +/// it. Note that verification is still experimental and may not +/// catch every error, or be maximally performant. For the +/// previous, unchecked, behavior use +/// `root_as_universe_unchecked`. +pub fn size_prefixed_root_as_universe_with_opts<'b, 'o>( + opts: &'o flatbuffers::VerifierOptions, + buf: &'b [u8], +) -> Result, flatbuffers::InvalidFlatbuffer> { + flatbuffers::size_prefixed_root_with_opts::>(opts, buf) +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a Universe and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid `Universe`. +pub unsafe fn root_as_universe_unchecked(buf: &[u8]) -> Universe { + flatbuffers::root_unchecked::(buf) +} +#[inline] +/// Assumes, without verification, that a buffer of bytes contains a size prefixed Universe and returns it. +/// # Safety +/// Callers must trust the given bytes do indeed contain a valid size prefixed `Universe`. +pub unsafe fn size_prefixed_root_as_universe_unchecked(buf: &[u8]) -> Universe { + flatbuffers::size_prefixed_root_unchecked::(buf) +} +#[inline] +pub fn finish_universe_buffer<'a, 'b>( + fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, + root: flatbuffers::WIPOffset>) { + fbb.finish(root, None); +} + +#[inline] +pub fn finish_size_prefixed_universe_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset>) { + fbb.finish_size_prefixed(root, None); +} diff --git a/goldens/rust/generate.py b/goldens/rust/generate.py new file mode 100644 index 000000000..f3a568fef --- /dev/null +++ b/goldens/rust/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Rust specifics + flatc_golden(options=["--rust"] + options, schema=schema, prefix="rust") + + +def GenerateRust(): + flatc([], "basic.fbs") diff --git a/goldens/schema/basic.fbs b/goldens/schema/basic.fbs new file mode 100644 index 000000000..8034599c7 --- /dev/null +++ b/goldens/schema/basic.fbs @@ -0,0 +1,13 @@ +// This file should contain the basics of flatbuffers that all languages should +// support. + +table Galaxy { + num_stars:long; +} + +table Universe { + age:double; + galaxies:[Galaxy]; +} + +root_type Universe; \ No newline at end of file diff --git a/goldens/swift/basic_generated.swift b/goldens/swift/basic_generated.swift new file mode 100644 index 000000000..7ea2d68b6 --- /dev/null +++ b/goldens/swift/basic_generated.swift @@ -0,0 +1,84 @@ +// automatically generated by the FlatBuffers compiler, do not modify +// swiftlint:disable all +// swiftformat:disable all + +import FlatBuffers + +public struct Galaxy: FlatBufferObject, Verifiable { + + static func validateVersion() { FlatBuffersVersion_23_5_26() } + public var __buffer: ByteBuffer! { return _accessor.bb } + private var _accessor: Table + + private init(_ t: Table) { _accessor = t } + public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) } + + private enum VTOFFSET: VOffset { + case numStars = 4 + var v: Int32 { Int32(self.rawValue) } + var p: VOffset { self.rawValue } + } + + public var numStars: Int64 { let o = _accessor.offset(VTOFFSET.numStars.v); return o == 0 ? 0 : _accessor.readBuffer(of: Int64.self, at: o) } + public static func startGalaxy(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) } + public static func add(numStars: Int64, _ fbb: inout FlatBufferBuilder) { fbb.add(element: numStars, def: 0, at: VTOFFSET.numStars.p) } + public static func endGalaxy(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end } + public static func createGalaxy( + _ fbb: inout FlatBufferBuilder, + numStars: Int64 = 0 + ) -> Offset { + let __start = Galaxy.startGalaxy(&fbb) + Galaxy.add(numStars: numStars, &fbb) + return Galaxy.endGalaxy(&fbb, start: __start) + } + + public static func verify(_ 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.numStars.p, fieldName: "numStars", required: false, type: Int64.self) + _v.finish() + } +} + +public struct Universe: FlatBufferObject, Verifiable { + + static func validateVersion() { FlatBuffersVersion_23_5_26() } + public var __buffer: ByteBuffer! { return _accessor.bb } + private var _accessor: Table + + private init(_ t: Table) { _accessor = t } + public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) } + + private enum VTOFFSET: VOffset { + case age = 4 + case galaxies = 6 + var v: Int32 { Int32(self.rawValue) } + var p: VOffset { self.rawValue } + } + + public var age: Double { let o = _accessor.offset(VTOFFSET.age.v); return o == 0 ? 0.0 : _accessor.readBuffer(of: Double.self, at: o) } + public var hasGalaxies: Bool { let o = _accessor.offset(VTOFFSET.galaxies.v); return o == 0 ? false : true } + public var galaxiesCount: Int32 { let o = _accessor.offset(VTOFFSET.galaxies.v); return o == 0 ? 0 : _accessor.vector(count: o) } + public func galaxies(at index: Int32) -> Galaxy? { let o = _accessor.offset(VTOFFSET.galaxies.v); return o == 0 ? nil : Galaxy(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) } + public static func startUniverse(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 2) } + public static func add(age: Double, _ fbb: inout FlatBufferBuilder) { fbb.add(element: age, def: 0.0, at: VTOFFSET.age.p) } + public static func addVectorOf(galaxies: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: galaxies, at: VTOFFSET.galaxies.p) } + public static func endUniverse(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end } + public static func createUniverse( + _ fbb: inout FlatBufferBuilder, + age: Double = 0.0, + galaxiesVectorOffset galaxies: Offset = Offset() + ) -> Offset { + let __start = Universe.startUniverse(&fbb) + Universe.add(age: age, &fbb) + Universe.addVectorOf(galaxies: galaxies, &fbb) + return Universe.endUniverse(&fbb, start: __start) + } + + public static func verify(_ 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.age.p, fieldName: "age", required: false, type: Double.self) + try _v.visit(field: VTOFFSET.galaxies.p, fieldName: "galaxies", required: false, type: ForwardOffset, Galaxy>>.self) + _v.finish() + } +} + diff --git a/goldens/swift/generate.py b/goldens/swift/generate.py new file mode 100644 index 000000000..ccdb97e77 --- /dev/null +++ b/goldens/swift/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Swift specifics + flatc_golden(options=["--swift"] + options, schema=schema, prefix="swift") + + +def GenerateSwift(): + flatc([], "basic.fbs") diff --git a/goldens/ts/basic.ts b/goldens/ts/basic.ts new file mode 100644 index 000000000..76af441a9 --- /dev/null +++ b/goldens/ts/basic.ts @@ -0,0 +1,4 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +export { Galaxy } from './galaxy.js'; +export { Universe } from './universe.js'; diff --git a/goldens/ts/galaxy.ts b/goldens/ts/galaxy.ts new file mode 100644 index 000000000..8576cbf83 --- /dev/null +++ b/goldens/ts/galaxy.ts @@ -0,0 +1,46 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +export class Galaxy { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):Galaxy { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsGalaxy(bb:flatbuffers.ByteBuffer, obj?:Galaxy):Galaxy { + return (obj || new Galaxy()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsGalaxy(bb:flatbuffers.ByteBuffer, obj?:Galaxy):Galaxy { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Galaxy()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +numStars():bigint { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0'); +} + +static startGalaxy(builder:flatbuffers.Builder) { + builder.startObject(1); +} + +static addNumStars(builder:flatbuffers.Builder, numStars:bigint) { + builder.addFieldInt64(0, numStars, BigInt('0')); +} + +static endGalaxy(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createGalaxy(builder:flatbuffers.Builder, numStars:bigint):flatbuffers.Offset { + Galaxy.startGalaxy(builder); + Galaxy.addNumStars(builder, numStars); + return Galaxy.endGalaxy(builder); +} +} diff --git a/goldens/ts/generate.py b/goldens/ts/generate.py new file mode 100644 index 000000000..ee072fdd6 --- /dev/null +++ b/goldens/ts/generate.py @@ -0,0 +1,10 @@ +from golden_utils import flatc_golden + + +def flatc(options, schema): + # Wrap the golden flatc generator with Swift specifics + flatc_golden(options=["--ts"] + options, schema=schema, prefix="ts") + + +def GenerateTs(): + flatc([], "basic.fbs") diff --git a/goldens/ts/universe.ts b/goldens/ts/universe.ts new file mode 100644 index 000000000..2f8c26cff --- /dev/null +++ b/goldens/ts/universe.ts @@ -0,0 +1,84 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +import * as flatbuffers from 'flatbuffers'; + +import { Galaxy } from './galaxy.js'; + + +export class Universe { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):Universe { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsUniverse(bb:flatbuffers.ByteBuffer, obj?:Universe):Universe { + return (obj || new Universe()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsUniverse(bb:flatbuffers.ByteBuffer, obj?:Universe):Universe { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Universe()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +age():number { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0; +} + +galaxies(index: number, obj?:Galaxy):Galaxy|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? (obj || new Galaxy()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null; +} + +galaxiesLength():number { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0; +} + +static startUniverse(builder:flatbuffers.Builder) { + builder.startObject(2); +} + +static addAge(builder:flatbuffers.Builder, age:number) { + builder.addFieldFloat64(0, age, 0.0); +} + +static addGalaxies(builder:flatbuffers.Builder, galaxiesOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, galaxiesOffset, 0); +} + +static createGalaxiesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]!); + } + return builder.endVector(); +} + +static startGalaxiesVector(builder:flatbuffers.Builder, numElems:number) { + builder.startVector(4, numElems, 4); +} + +static endUniverse(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static finishUniverseBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) { + builder.finish(offset); +} + +static finishSizePrefixedUniverseBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) { + builder.finish(offset, undefined, true); +} + +static createUniverse(builder:flatbuffers.Builder, age:number, galaxiesOffset:flatbuffers.Offset):flatbuffers.Offset { + Universe.startUniverse(builder); + Universe.addAge(builder, age); + Universe.addGalaxies(builder, galaxiesOffset); + return Universe.endUniverse(builder); +} +} diff --git a/grpc/examples/python/greeter/models/HelloReply.py b/grpc/examples/python/greeter/models/HelloReply.py index bf182fc85..b1adc8c31 100644 --- a/grpc/examples/python/greeter/models/HelloReply.py +++ b/grpc/examples/python/greeter/models/HelloReply.py @@ -40,7 +40,7 @@ def Start(builder): def HelloReplyAddMessage(builder, message): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(message), 0) -def AddMessage(builder: flatbuffers.Builder, message: int): +def AddMessage(builder, message): HelloReplyAddMessage(builder, message) def HelloReplyEnd(builder): diff --git a/grpc/examples/python/greeter/models/HelloRequest.py b/grpc/examples/python/greeter/models/HelloRequest.py index 9df6b22c9..db217dd21 100644 --- a/grpc/examples/python/greeter/models/HelloRequest.py +++ b/grpc/examples/python/greeter/models/HelloRequest.py @@ -40,7 +40,7 @@ def Start(builder): def HelloRequestAddName(builder, name): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0) -def AddName(builder: flatbuffers.Builder, name: int): +def AddName(builder, name): HelloRequestAddName(builder, name) def HelloRequestEnd(builder): diff --git a/grpc/examples/swift/Greeter/Sources/Model/greeter_generated.swift b/grpc/examples/swift/Greeter/Sources/Model/greeter_generated.swift index 91060c476..26d4c65bb 100644 --- a/grpc/examples/swift/Greeter/Sources/Model/greeter_generated.swift +++ b/grpc/examples/swift/Greeter/Sources/Model/greeter_generated.swift @@ -6,7 +6,7 @@ import FlatBuffers public struct models_HelloReply: FlatBufferObject, Verifiable { - static func validateVersion() { FlatBuffersVersion_23_3_3() } + static func validateVersion() { FlatBuffersVersion_23_5_26() } public var __buffer: ByteBuffer! { return _accessor.bb } private var _accessor: Table @@ -53,7 +53,7 @@ extension models_HelloReply: Encodable { public struct models_HelloRequest: FlatBufferObject, Verifiable { - static func validateVersion() { FlatBuffersVersion_23_3_3() } + static func validateVersion() { FlatBuffersVersion_23_5_26() } public var __buffer: ByteBuffer! { return _accessor.bb } private var _accessor: Table diff --git a/include/flatbuffers/array.h b/include/flatbuffers/array.h index 2ff58c6fb..f4bfbf054 100644 --- a/include/flatbuffers/array.h +++ b/include/flatbuffers/array.h @@ -17,6 +17,7 @@ #ifndef FLATBUFFERS_ARRAY_H_ #define FLATBUFFERS_ARRAY_H_ +#include #include #include "flatbuffers/base.h" @@ -37,7 +38,7 @@ template class Array { public: typedef uint16_t size_type; typedef typename IndirectHelper::return_type return_type; - typedef VectorConstIterator const_iterator; + typedef VectorConstIterator const_iterator; typedef VectorReverseIterator const_reverse_iterator; // If T is a LE-scalar or a struct (!scalar_tag::value). @@ -158,11 +159,13 @@ template class Array { // Specialization for Array[struct] with access using Offset pointer. // This specialization used by idl_gen_text.cpp. -template class Array, length> { +template class OffsetT> +class Array, length> { static_assert(flatbuffers::is_same::value, "unexpected type T"); public: typedef const void *return_type; + typedef uint16_t size_type; const uint8_t *Data() const { return data_; } diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h index 98a02262c..5c4cae791 100644 --- a/include/flatbuffers/base.h +++ b/include/flatbuffers/base.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -139,8 +140,8 @@ #endif // !defined(FLATBUFFERS_LITTLEENDIAN) #define FLATBUFFERS_VERSION_MAJOR 23 -#define FLATBUFFERS_VERSION_MINOR 3 -#define FLATBUFFERS_VERSION_REVISION 3 +#define FLATBUFFERS_VERSION_MINOR 5 +#define FLATBUFFERS_VERSION_REVISION 26 #define FLATBUFFERS_STRING_EXPAND(X) #X #define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) namespace flatbuffers { @@ -278,14 +279,14 @@ namespace flatbuffers { #endif // !FLATBUFFERS_LOCALE_INDEPENDENT // Suppress Undefined Behavior Sanitizer (recoverable only). Usage: -// - __suppress_ubsan__("undefined") -// - __suppress_ubsan__("signed-integer-overflow") +// - FLATBUFFERS_SUPPRESS_UBSAN("undefined") +// - FLATBUFFERS_SUPPRESS_UBSAN("signed-integer-overflow") #if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7)) - #define __suppress_ubsan__(type) __attribute__((no_sanitize(type))) + #define FLATBUFFERS_SUPPRESS_UBSAN(type) __attribute__((no_sanitize(type))) #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) - #define __suppress_ubsan__(type) __attribute__((no_sanitize_undefined)) + #define FLATBUFFERS_SUPPRESS_UBSAN(type) __attribute__((no_sanitize_undefined)) #else - #define __suppress_ubsan__(type) + #define FLATBUFFERS_SUPPRESS_UBSAN(type) #endif // This is constexpr function used for checking compile-time constants. @@ -323,9 +324,11 @@ namespace flatbuffers { // Also, using a consistent offset type maintains compatibility of serialized // offset values between 32bit and 64bit systems. typedef uint32_t uoffset_t; +typedef uint64_t uoffset64_t; // Signed offsets for references that can go in both directions. typedef int32_t soffset_t; +typedef int64_t soffset64_t; // Offset/index used in v-tables, can be changed to uint8_t in // format forks to save a bit of space if desired. @@ -334,7 +337,8 @@ typedef uint16_t voffset_t; typedef uintmax_t largest_scalar_t; // In 32bits, this evaluates to 2GB - 1 -#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1) +#define FLATBUFFERS_MAX_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset_t>::max() +#define FLATBUFFERS_MAX_64_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset64_t>::max() // The minimum size buffer that can be a valid flatbuffer. // Includes the offset to the root table (uoffset_t), the offset to the vtable @@ -418,7 +422,7 @@ template T EndianScalar(T t) { template // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. -__suppress_ubsan__("alignment") +FLATBUFFERS_SUPPRESS_UBSAN("alignment") T ReadScalar(const void *p) { return EndianScalar(*reinterpret_cast(p)); } @@ -432,13 +436,13 @@ T ReadScalar(const void *p) { template // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. -__suppress_ubsan__("alignment") +FLATBUFFERS_SUPPRESS_UBSAN("alignment") void WriteScalar(void *p, T t) { *reinterpret_cast(p) = EndianScalar(t); } template struct Offset; -template __suppress_ubsan__("alignment") void WriteScalar(void *p, Offset t) { +template FLATBUFFERS_SUPPRESS_UBSAN("alignment") void WriteScalar(void *p, Offset t) { *reinterpret_cast(p) = EndianScalar(t.o); } @@ -449,7 +453,7 @@ template __suppress_ubsan__("alignment") void WriteScalar(void *p, O // Computes how many bytes you'd have to pad to be able to write an // "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in // memory). -__suppress_ubsan__("unsigned-integer-overflow") +FLATBUFFERS_SUPPRESS_UBSAN("unsigned-integer-overflow") inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { return ((~buf_size) + 1) & (scalar_size - 1); } diff --git a/include/flatbuffers/buffer.h b/include/flatbuffers/buffer.h index e26a153c3..94d4f7903 100644 --- a/include/flatbuffers/buffer.h +++ b/include/flatbuffers/buffer.h @@ -25,14 +25,33 @@ namespace flatbuffers { // Wrapper for uoffset_t to allow safe template specialization. // Value is allowed to be 0 to indicate a null object (see e.g. AddOffset). -template struct Offset { - uoffset_t o; +template struct Offset { + // The type of offset to use. + typedef uoffset_t offset_type; + + offset_type o; Offset() : o(0) {} - Offset(uoffset_t _o) : o(_o) {} - Offset Union() const { return Offset(o); } + Offset(const offset_type _o) : o(_o) {} + Offset<> Union() const { return o; } bool IsNull() const { return !o; } }; +// Wrapper for uoffset64_t Offsets. +template struct Offset64 { + // The type of offset to use. + typedef uoffset64_t offset_type; + + offset_type o; + Offset64() : o(0) {} + Offset64(const offset_type offset) : o(offset) {} + Offset64<> Union() const { return o; } + bool IsNull() const { return !o; } +}; + +// Litmus check for ensuring the Offsets are the expected size. +static_assert(sizeof(Offset<>) == 4, "Offset has wrong size"); +static_assert(sizeof(Offset64<>) == 8, "Offset64 has wrong size"); + inline void EndianCheck() { int endiantest = 1; // If this fails, see FLATBUFFERS_LITTLEENDIAN above. @@ -75,35 +94,59 @@ template struct IndirectHelper { typedef T return_type; typedef T mutable_return_type; static const size_t element_stride = sizeof(T); - static return_type Read(const uint8_t *p, uoffset_t i) { + + static return_type Read(const uint8_t *p, const size_t i) { return EndianScalar((reinterpret_cast(p))[i]); } - static return_type Read(uint8_t *p, uoffset_t i) { - return Read(const_cast(p), i); + static mutable_return_type Read(uint8_t *p, const size_t i) { + return reinterpret_cast( + Read(const_cast(p), i)); } }; -template struct IndirectHelper> { + +// For vector of Offsets. +template class OffsetT> +struct IndirectHelper> { typedef const T *return_type; typedef T *mutable_return_type; - static const size_t element_stride = sizeof(uoffset_t); - static return_type Read(const uint8_t *p, uoffset_t i) { - p += i * sizeof(uoffset_t); - return reinterpret_cast(p + ReadScalar(p)); + typedef typename OffsetT::offset_type offset_type; + static const offset_type element_stride = sizeof(offset_type); + + static return_type Read(const uint8_t *const p, const offset_type i) { + // Offsets are relative to themselves, so first update the pointer to + // point to the offset location. + const uint8_t *const offset_location = p + i * element_stride; + + // Then read the scalar value of the offset (which may be 32 or 64-bits) and + // then determine the relative location from the offset location. + return reinterpret_cast( + offset_location + ReadScalar(offset_location)); } - static mutable_return_type Read(uint8_t *p, uoffset_t i) { - p += i * sizeof(uoffset_t); - return reinterpret_cast(p + ReadScalar(p)); + static mutable_return_type Read(uint8_t *const p, const offset_type i) { + // Offsets are relative to themselves, so first update the pointer to + // point to the offset location. + uint8_t *const offset_location = p + i * element_stride; + + // Then read the scalar value of the offset (which may be 32 or 64-bits) and + // then determine the relative location from the offset location. + return reinterpret_cast( + offset_location + ReadScalar(offset_location)); } }; + +// For vector of structs. template struct IndirectHelper { typedef const T *return_type; typedef T *mutable_return_type; static const size_t element_stride = sizeof(T); - static return_type Read(const uint8_t *p, uoffset_t i) { - return reinterpret_cast(p + i * sizeof(T)); + + static return_type Read(const uint8_t *const p, const size_t i) { + // Structs are stored inline, relative to the first struct pointer. + return reinterpret_cast(p + i * element_stride); } - static mutable_return_type Read(uint8_t *p, uoffset_t i) { - return reinterpret_cast(p + i * sizeof(T)); + static mutable_return_type Read(uint8_t *const p, const size_t i) { + // Structs are stored inline, relative to the first struct pointer. + return reinterpret_cast(p + i * element_stride); } }; @@ -130,23 +173,25 @@ inline bool BufferHasIdentifier(const void *buf, const char *identifier, /// @cond FLATBUFFERS_INTERNAL // Helpers to get a typed pointer to the root object contained in the buffer. template T *GetMutableRoot(void *buf) { + if (!buf) return nullptr; EndianCheck(); return reinterpret_cast( reinterpret_cast(buf) + EndianScalar(*reinterpret_cast(buf))); } -template T *GetMutableSizePrefixedRoot(void *buf) { - return GetMutableRoot(reinterpret_cast(buf) + - sizeof(uoffset_t)); +template +T *GetMutableSizePrefixedRoot(void *buf) { + return GetMutableRoot(reinterpret_cast(buf) + sizeof(SizeT)); } template const T *GetRoot(const void *buf) { return GetMutableRoot(const_cast(buf)); } -template const T *GetSizePrefixedRoot(const void *buf) { - return GetRoot(reinterpret_cast(buf) + sizeof(uoffset_t)); +template +const T *GetSizePrefixedRoot(const void *buf) { + return GetRoot(reinterpret_cast(buf) + sizeof(SizeT)); } } // namespace flatbuffers diff --git a/include/flatbuffers/code_generator.h b/include/flatbuffers/code_generator.h index 85d4430cf..2971e556e 100644 --- a/include/flatbuffers/code_generator.h +++ b/include/flatbuffers/code_generator.h @@ -23,6 +23,10 @@ namespace flatbuffers { +struct CodeGenOptions { + std::string output_path; +}; + // A code generator interface for producing converting flatbuffer schema into // code. class CodeGenerator { @@ -36,15 +40,28 @@ class CodeGenerator { NOT_IMPLEMENTED = 3 }; + std::string status_detail; + // Generate code from the provided `parser`. // // DEPRECATED: prefer using the other overload of GenerateCode for bfbs. virtual Status GenerateCode(const Parser &parser, const std::string &path, const std::string &filename) = 0; + // Generate code from the provided `parser` and place it in the output. + virtual Status GenerateCodeString(const Parser &parser, + const std::string &filename, + std::string &output) { + (void)parser; + (void)filename; + (void)output; + return Status::NOT_IMPLEMENTED; + } + // Generate code from the provided `buffer` of given `length`. The buffer is a // serialized reflection.fbs. - virtual Status GenerateCode(const uint8_t *buffer, int64_t length) = 0; + virtual Status GenerateCode(const uint8_t *buffer, int64_t length, + const CodeGenOptions &options) = 0; virtual Status GenerateMakeRule(const Parser &parser, const std::string &path, const std::string &filename, diff --git a/include/flatbuffers/code_generators.h b/include/flatbuffers/code_generators.h index 727552118..fc030d439 100644 --- a/include/flatbuffers/code_generators.h +++ b/include/flatbuffers/code_generators.h @@ -229,6 +229,10 @@ class TypedFloatConstantGenerator : public FloatConstantGenerator { const std::string neg_inf_number_; }; +std::string JavaCSharpMakeRule(const bool java, const Parser &parser, + const std::string &path, + const std::string &file_name); + } // namespace flatbuffers #endif // FLATBUFFERS_CODE_GENERATORS_H_ diff --git a/include/flatbuffers/flatbuffer_builder.h b/include/flatbuffers/flatbuffer_builder.h index b9015d850..a33c89669 100644 --- a/include/flatbuffers/flatbuffer_builder.h +++ b/include/flatbuffers/flatbuffer_builder.h @@ -18,12 +18,15 @@ #define FLATBUFFERS_FLATBUFFER_BUILDER_H_ #include +#include #include #include +#include #include "flatbuffers/allocator.h" #include "flatbuffers/array.h" #include "flatbuffers/base.h" +#include "flatbuffers/buffer.h" #include "flatbuffers/buffer_ref.h" #include "flatbuffers/default_allocator.h" #include "flatbuffers/detached_buffer.h" @@ -40,8 +43,9 @@ namespace flatbuffers { // Converts a Field ID to a virtual table offset. inline voffset_t FieldIndexToOffset(voffset_t field_id) { // Should correspond to what EndTable() below builds up. - const int fixed_fields = 2; // Vtable size and Object Size. - return static_cast((field_id + fixed_fields) * sizeof(voffset_t)); + const voffset_t fixed_fields = + 2 * sizeof(voffset_t); // Vtable size and Object Size. + return fixed_fields + field_id * sizeof(voffset_t); } template> @@ -68,8 +72,13 @@ T *data(std::vector &v) { /// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/ /// `CreateVector` functions. Do this is depth-first order to build up a tree to /// the root. `Finish()` wraps up the buffer ready for transport. -class FlatBufferBuilder { +template class FlatBufferBuilderImpl { public: + // This switches the size type of the builder, based on if its 64-bit aware + // (uoffset64_t) or not (uoffset_t). + typedef + typename std::conditional::type SizeT; + /// @brief Default constructor for FlatBufferBuilder. /// @param[in] initial_size The initial size of the buffer, in bytes. Defaults /// to `1024`. @@ -81,13 +90,16 @@ class FlatBufferBuilder { /// minimum alignment upon reallocation. Only needed if you intend to store /// types with custom alignment AND you wish to read the buffer in-place /// directly after creation. - explicit FlatBufferBuilder( + explicit FlatBufferBuilderImpl( size_t initial_size = 1024, Allocator *allocator = nullptr, bool own_allocator = false, size_t buffer_minalign = AlignOf()) - : buf_(initial_size, allocator, own_allocator, buffer_minalign), + : buf_(initial_size, allocator, own_allocator, buffer_minalign, + static_cast(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE + : FLATBUFFERS_MAX_BUFFER_SIZE)), num_field_loc(0), max_voffset_(0), + length_of_64_bit_region_(0), nested(false), finished(false), minalign_(1), @@ -98,10 +110,13 @@ class FlatBufferBuilder { } /// @brief Move constructor for FlatBufferBuilder. - FlatBufferBuilder(FlatBufferBuilder &&other) noexcept - : buf_(1024, nullptr, false, AlignOf()), + FlatBufferBuilderImpl(FlatBufferBuilderImpl &&other) noexcept + : buf_(1024, nullptr, false, AlignOf(), + static_cast(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE + : FLATBUFFERS_MAX_BUFFER_SIZE)), num_field_loc(0), max_voffset_(0), + length_of_64_bit_region_(0), nested(false), finished(false), minalign_(1), @@ -116,18 +131,19 @@ class FlatBufferBuilder { } /// @brief Move assignment operator for FlatBufferBuilder. - FlatBufferBuilder &operator=(FlatBufferBuilder &&other) noexcept { + FlatBufferBuilderImpl &operator=(FlatBufferBuilderImpl &&other) noexcept { // Move construct a temporary and swap idiom - FlatBufferBuilder temp(std::move(other)); + FlatBufferBuilderImpl temp(std::move(other)); Swap(temp); return *this; } - void Swap(FlatBufferBuilder &other) { + void Swap(FlatBufferBuilderImpl &other) { using std::swap; buf_.swap(other.buf_); swap(num_field_loc, other.num_field_loc); swap(max_voffset_, other.max_voffset_); + swap(length_of_64_bit_region_, other.length_of_64_bit_region_); swap(nested, other.nested); swap(finished, other.finished); swap(minalign_, other.minalign_); @@ -136,7 +152,7 @@ class FlatBufferBuilder { swap(string_pool, other.string_pool); } - ~FlatBufferBuilder() { + ~FlatBufferBuilderImpl() { if (string_pool) delete string_pool; } @@ -153,12 +169,36 @@ class FlatBufferBuilder { nested = false; finished = false; minalign_ = 1; + length_of_64_bit_region_ = 0; if (string_pool) string_pool->clear(); } /// @brief The current size of the serialized buffer, counting from the end. + /// @return Returns an `SizeT` with the current size of the buffer. + SizeT GetSize() const { return buf_.size(); } + + /// @brief The current size of the serialized buffer relative to the end of + /// the 32-bit region. /// @return Returns an `uoffset_t` with the current size of the buffer. - uoffset_t GetSize() const { return buf_.size(); } + template + // Only enable this method for the 64-bit builder, as only that builder is + // concerned with the 32/64-bit boundary, and should be the one to bare any + // run time costs. + typename std::enable_if::type GetSizeRelative32BitRegion() + const { + //[32-bit region][64-bit region] + // [XXXXXXXXXXXXXXXXXXX] GetSize() + // [YYYYYYYYYYYYY] length_of_64_bit_region_ + // [ZZZZ] return size + return static_cast(GetSize() - length_of_64_bit_region_); + } + + template + // Only enable this method for the 32-bit builder. + typename std::enable_if::type GetSizeRelative32BitRegion() + const { + return static_cast(GetSize()); + } /// @brief Get the serialized buffer (after you call `Finish()`). /// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the @@ -270,14 +310,16 @@ class FlatBufferBuilder { } // Write a single aligned scalar to the buffer - template uoffset_t PushElement(T element) { + template + ReturnT PushElement(T element) { AssertScalarT(); Align(sizeof(T)); buf_.push_small(EndianScalar(element)); - return GetSize(); + return CalculateOffset(); } - template uoffset_t PushElement(Offset off) { + template class OffsetT = Offset> + uoffset_t PushElement(OffsetT off) { // Special case for offsets: see ReferTo below. return PushElement(ReferTo(off.o)); } @@ -307,11 +349,16 @@ class FlatBufferBuilder { AddElement(field, ReferTo(off.o), static_cast(0)); } + template void AddOffset(voffset_t field, Offset64 off) { + if (off.IsNull()) return; // Don't store. + AddElement(field, ReferTo(off.o), static_cast(0)); + } + template void AddStruct(voffset_t field, const T *structptr) { if (!structptr) return; // Default, don't store. Align(AlignOf()); buf_.push_small(*structptr); - TrackField(field, GetSize()); + TrackField(field, CalculateOffset()); } void AddStructOffset(voffset_t field, uoffset_t off) { @@ -322,12 +369,29 @@ class FlatBufferBuilder { // This function converts them to be relative to the current location // in the buffer (when stored here), pointing upwards. uoffset_t ReferTo(uoffset_t off) { - // Align to ensure GetSize() below is correct. + // Align to ensure GetSizeRelative32BitRegion() below is correct. Align(sizeof(uoffset_t)); - // Offset must refer to something already in buffer. - const uoffset_t size = GetSize(); + // 32-bit offsets are relative to the tail of the 32-bit region of the + // buffer. For most cases (without 64-bit entities) this is equivalent to + // size of the whole buffer (e.g. GetSize()) + return ReferTo(off, GetSizeRelative32BitRegion()); + } + + uoffset64_t ReferTo(uoffset64_t off) { + // Align to ensure GetSize() below is correct. + Align(sizeof(uoffset64_t)); + // 64-bit offsets are relative to tail of the whole buffer + return ReferTo(off, GetSize()); + } + + template T ReferTo(const T off, const T2 size) { FLATBUFFERS_ASSERT(off && off <= size); - return size - off + static_cast(sizeof(uoffset_t)); + return size - off + static_cast(sizeof(T)); + } + + template T ReferTo(const T off, const T size) { + FLATBUFFERS_ASSERT(off && off <= size); + return size - off + static_cast(sizeof(T)); } void NotNested() { @@ -349,7 +413,7 @@ class FlatBufferBuilder { uoffset_t StartTable() { NotNested(); nested = true; - return GetSize(); + return GetSizeRelative32BitRegion(); } // This finishes one serialized object by generating the vtable if it's a @@ -360,7 +424,9 @@ class FlatBufferBuilder { FLATBUFFERS_ASSERT(nested); // Write the vtable offset, which is the start of any Table. // We fill its value later. - auto vtableoffsetloc = PushElement(0); + // This is relative to the end of the 32-bit region. + const uoffset_t vtable_offset_loc = + static_cast(PushElement(0)); // Write a vtable, which consists entirely of voffset_t elements. // It starts with the number of offsets, followed by a type id, followed // by the offsets themselves. In reverse: @@ -370,7 +436,7 @@ class FlatBufferBuilder { (std::max)(static_cast(max_voffset_ + sizeof(voffset_t)), FieldIndexToOffset(0)); buf_.fill_big(max_voffset_); - auto table_object_size = vtableoffsetloc - start; + const uoffset_t table_object_size = vtable_offset_loc - start; // Vtable use 16bit offsets. FLATBUFFERS_ASSERT(table_object_size < 0x10000); WriteScalar(buf_.data() + sizeof(voffset_t), @@ -380,7 +446,8 @@ class FlatBufferBuilder { for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc); it < buf_.scratch_end(); it += sizeof(FieldLoc)) { auto field_location = reinterpret_cast(it); - auto pos = static_cast(vtableoffsetloc - field_location->off); + const voffset_t pos = + static_cast(vtable_offset_loc - field_location->off); // If this asserts, it means you've set a field twice. FLATBUFFERS_ASSERT( !ReadScalar(buf_.data() + field_location->id)); @@ -389,7 +456,7 @@ class FlatBufferBuilder { ClearOffsets(); auto vt1 = reinterpret_cast(buf_.data()); auto vt1_size = ReadScalar(vt1); - auto vt_use = GetSize(); + auto vt_use = GetSizeRelative32BitRegion(); // See if we already have generated a vtable with this exact same // layout before. If so, make it point to the old one, remove this one. if (dedup_vtables_) { @@ -400,23 +467,24 @@ class FlatBufferBuilder { auto vt2_size = ReadScalar(vt2); if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue; vt_use = *vt_offset_ptr; - buf_.pop(GetSize() - vtableoffsetloc); + buf_.pop(GetSizeRelative32BitRegion() - vtable_offset_loc); break; } } // If this is a new vtable, remember it. - if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); } + if (vt_use == GetSizeRelative32BitRegion()) { + buf_.scratch_push_small(vt_use); + } // Fill the vtable offset we created above. - // The offset points from the beginning of the object to where the - // vtable is stored. + // The offset points from the beginning of the object to where the vtable is + // stored. // Offsets default direction is downward in memory for future format // flexibility (storing all vtables at the start of the file). - WriteScalar(buf_.data_at(vtableoffsetloc), + WriteScalar(buf_.data_at(vtable_offset_loc + length_of_64_bit_region_), static_cast(vt_use) - - static_cast(vtableoffsetloc)); - + static_cast(vtable_offset_loc)); nested = false; - return vtableoffsetloc; + return vtable_offset_loc; } FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]]) @@ -426,14 +494,20 @@ class FlatBufferBuilder { // This checks a required field has been set in a given table that has // just been constructed. - template void Required(Offset table, voffset_t field); + template void Required(Offset table, voffset_t field) { + auto table_ptr = reinterpret_cast(buf_.data_at(table.o)); + bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; + // If this fails, the caller will show what field needs to be set. + FLATBUFFERS_ASSERT(ok); + (void)ok; + } uoffset_t StartStruct(size_t alignment) { Align(alignment); - return GetSize(); + return GetSizeRelative32BitRegion(); } - uoffset_t EndStruct() { return GetSize(); } + uoffset_t EndStruct() { return GetSizeRelative32BitRegion(); } void ClearOffsets() { buf_.scratch_pop(num_field_loc * sizeof(FieldLoc)); @@ -442,15 +516,18 @@ class FlatBufferBuilder { } // Aligns such that when "len" bytes are written, an object can be written - // after it with "alignment" without padding. + // after it (forward in the buffer) with "alignment" without padding. void PreAlign(size_t len, size_t alignment) { if (len == 0) return; TrackMinAlign(alignment); buf_.fill(PaddingBytes(GetSize() + len, alignment)); } - template void PreAlign(size_t len) { - AssertScalarT(); - PreAlign(len, AlignOf()); + + // Aligns such than when "len" bytes are written, an object of type `AlignT` + // can be written after it (forward in the buffer) without padding. + template void PreAlign(size_t len) { + AssertScalarT(); + PreAlign(len, AlignOf()); } /// @endcond @@ -458,43 +535,45 @@ class FlatBufferBuilder { /// @param[in] str A const char pointer to the data to be stored as a string. /// @param[in] len The number of bytes that should be stored from `str`. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char *str, size_t len) { - NotNested(); - PreAlign(len + 1); // Always 0-terminated. - buf_.fill(1); - PushBytes(reinterpret_cast(str), len); - PushElement(static_cast(len)); - return Offset(GetSize()); + template class OffsetT = Offset> + OffsetT CreateString(const char *str, size_t len) { + CreateStringImpl(str, len); + return OffsetT( + CalculateOffset::offset_type>()); } /// @brief Store a string in the buffer, which is null-terminated. /// @param[in] str A const char pointer to a C-string to add to the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char *str) { - return CreateString(str, strlen(str)); + template class OffsetT = Offset> + OffsetT CreateString(const char *str) { + return CreateString(str, strlen(str)); } /// @brief Store a string in the buffer, which is null-terminated. /// @param[in] str A char pointer to a C-string to add to the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(char *str) { - return CreateString(str, strlen(str)); + template class OffsetT = Offset> + OffsetT CreateString(char *str) { + return CreateString(str, strlen(str)); } /// @brief Store a string in the buffer, which can contain any binary data. /// @param[in] str A const reference to a std::string to store in the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const std::string &str) { - return CreateString(str.c_str(), str.length()); + template class OffsetT = Offset> + OffsetT CreateString(const std::string &str) { + return CreateString(str.c_str(), str.length()); } - // clang-format off +// clang-format off #ifdef FLATBUFFERS_HAS_STRING_VIEW /// @brief Store a string in the buffer, which can contain any binary data. /// @param[in] str A const string_view to copy in to the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(flatbuffers::string_view str) { - return CreateString(str.data(), str.size()); + template