Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream Google changes #8362

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/flatbuffers/idl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <map>
#include <memory>
#include <stack>
#include <string>
#include <vector>

#include "flatbuffers/base.h"
Expand Down Expand Up @@ -778,6 +779,10 @@ struct IDLOptions {
// make the flatbuffer more compact.
bool set_empty_vectors_to_null;

/********************************** swift ***********************************/
std::string swift_module_mappings;
std::vector<std::string> swift_includes;

/*********************************** gRPC ***********************************/
std::string grpc_filename_suffix;
bool grpc_use_system_headers;
Expand Down
4 changes: 4 additions & 0 deletions include/flatbuffers/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <ctype.h>
#include <errno.h>

#include <vector>

#include "flatbuffers/base.h"
#include "flatbuffers/stl_emulation.h"

Expand Down Expand Up @@ -407,6 +409,8 @@ inline bool StringIsFlatbufferNegativeInfinity(const std::string &s) {
return s == "-inf" || s == "-infinity";
}

std::vector<std::string> StringSplit(const std::string &s, char delim);

typedef bool (*LoadFileFunction)(const char *filename, bool binary,
std::string *dest);
typedef bool (*FileExistsFunction)(const char *filename);
Expand Down
72 changes: 42 additions & 30 deletions java/src/main/java/com/google/flatbuffers/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.google.flatbuffers;

import static com.google.flatbuffers.Constants.*;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

Expand All @@ -43,6 +44,15 @@ public class Table {
*/
public ByteBuffer getByteBuffer() { return bb; }

/**
* Get the position in the underlying ByteBuffer.
*
* @return Returns the Table's position in the underlying ByteBuffer.
*/
public int getPosition() {
return bb_pos;
}

/**
* Look up a field in the vtable.
*
Expand Down Expand Up @@ -82,10 +92,10 @@ protected static int __indirect(int offset, ByteBuffer bb) {
/**
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
*
* This allocates a new string and converts to wide chars upon each access,
* which is not very efficient. Instead, each FlatBuffer string also comes with an
* accessor based on __vector_as_bytebuffer below, which is much more efficient,
* assuming your Java program can handle UTF-8 data directly.
* <p>This allocates a new string and converts to wide chars upon each access, which is not very
* efficient. Instead, each FlatBuffer string also comes with an accessor based on
* __vector_as_bytebuffer below, which is much more efficient, assuming your Java program can
* handle UTF-8 data directly.
*
* @param offset An `int` index into the Table's ByteBuffer.
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
Expand All @@ -97,10 +107,10 @@ protected String __string(int offset) {
/**
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
*
* This allocates a new string and converts to wide chars upon each access,
* which is not very efficient. Instead, each FlatBuffer string also comes with an
* accessor based on __vector_as_bytebuffer below, which is much more efficient,
* assuming your Java program can handle UTF-8 data directly.
* <p>This allocates a new string and converts to wide chars upon each access, which is not very
* efficient. Instead, each FlatBuffer string also comes with an accessor based on
* __vector_as_bytebuffer below, which is much more efficient, assuming your Java program can
* handle UTF-8 data directly.
*
* @param offset An `int` index into the Table's ByteBuffer.
* @param bb Table ByteBuffer used to read a string at given offset.
Expand Down Expand Up @@ -133,15 +143,15 @@ protected int __vector_len(int offset) {
*/
protected int __vector(int offset) {
offset += bb_pos;
return offset + bb.getInt(offset) + SIZEOF_INT; // data starts after the length
return offset + bb.getInt(offset) + SIZEOF_INT; // data starts after the length
}

/**
* Get a whole vector as a ByteBuffer.
*
* This is efficient, since it only allocates a new {@link ByteBuffer} object,
* but does not actually copy the data, it still refers to the same bytes
* as the original ByteBuffer. Also useful with nested FlatBuffers, etc.
* <p>This is efficient, since it only allocates a new {@link ByteBuffer} object, but does not
* actually copy the data, it still refers to the same bytes as the original ByteBuffer. Also
* useful with nested FlatBuffers, etc.
*
* @param vector_offset The position of the vector in the byte buffer
* @param elem_size The size of each element in the array
Expand All @@ -160,8 +170,8 @@ protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) {
/**
* Initialize vector as a ByteBuffer.
*
* This is more efficient than using duplicate, since it doesn't copy the data
* nor allocattes a new {@link ByteBuffer}, creating no garbage to be collected.
* <p>This is more efficient than using duplicate, since it doesn't copy the data nor allocattes a
* new {@link ByteBuffer}, creating no garbage to be collected.
*
* @param bb The {@link ByteBuffer} for the array
* @param vector_offset The position of the vector in the byte buffer
Expand Down Expand Up @@ -205,17 +215,16 @@ protected static Table __union(Table t, int offset, ByteBuffer bb) {
/**
* Check if a {@link ByteBuffer} contains a file identifier.
*
* @param bb A {@code ByteBuffer} to check if it contains the identifier
* `ident`.
* @param bb A {@code ByteBuffer} to check if it contains the identifier `ident`.
* @param ident A `String` identifier of the FlatBuffer file.
* @return True if the buffer contains the file identifier
*/
protected static boolean __has_identifier(ByteBuffer bb, String ident) {
if (ident.length() != FILE_IDENTIFIER_LENGTH)
throw new AssertionError("FlatBuffers: file identifier must be length " +
FILE_IDENTIFIER_LENGTH);
throw new AssertionError(
"FlatBuffers: file identifier must be length " + FILE_IDENTIFIER_LENGTH);
for (int i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
if (ident.charAt(i) != (char)bb.get(bb.position() + SIZEOF_INT + i)) return false;
if (ident.charAt(i) != (char) bb.get(bb.position() + SIZEOF_INT + i)) return false;
}
return true;
}
Expand All @@ -229,11 +238,13 @@ protected static boolean __has_identifier(ByteBuffer bb, String ident) {
protected void sortTables(int[] offsets, final ByteBuffer bb) {
Integer[] off = new Integer[offsets.length];
for (int i = 0; i < offsets.length; i++) off[i] = offsets[i];
java.util.Arrays.sort(off, new java.util.Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return keysCompare(o1, o2, bb);
}
});
java.util.Arrays.sort(
off,
new java.util.Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return keysCompare(o1, o2, bb);
}
});
for (int i = 0; i < offsets.length; i++) offsets[i] = off[i];
}

Expand All @@ -244,7 +255,9 @@ public int compare(Integer o1, Integer o2) {
* @param o2 An 'Integer' index of the second key into the bb.
* @param bb A {@code ByteBuffer} to get the keys.
*/
protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) { return 0; }
protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) {
return 0;
}

/**
* Compare two strings in the buffer.
Expand All @@ -261,7 +274,7 @@ protected static int compareStrings(int offset_1, int offset_2, ByteBuffer bb) {
int startPos_1 = offset_1 + SIZEOF_INT;
int startPos_2 = offset_2 + SIZEOF_INT;
int len = Math.min(len_1, len_2);
for(int i = 0; i < len; i++) {
for (int i = 0; i < len; i++) {
if (bb.get(i + startPos_1) != bb.get(i + startPos_2))
return bb.get(i + startPos_1) - bb.get(i + startPos_2);
}
Expand All @@ -282,19 +295,18 @@ protected static int compareStrings(int offset_1, byte[] key, ByteBuffer bb) {
int startPos_1 = offset_1 + Constants.SIZEOF_INT;
int len = Math.min(len_1, len_2);
for (int i = 0; i < len; i++) {
if (bb.get(i + startPos_1) != key[i])
return bb.get(i + startPos_1) - key[i];
if (bb.get(i + startPos_1) != key[i]) return bb.get(i + startPos_1) - key[i];
}
return len_1 - len_2;
}

/**
* Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
*
* This method exists primarily to allow recycling Table instances without risking memory leaks
* <p>This method exists primarily to allow recycling Table instances without risking memory leaks
* due to {@code ByteBuffer} references.
*/
protected void __reset(int _i, ByteBuffer _bb) {
protected void __reset(int _i, ByteBuffer _bb) {
bb = _bb;
if (bb != null) {
bb_pos = _i;
Expand Down
13 changes: 13 additions & 0 deletions src/flatc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "flatbuffers/flatc.h"

#include <algorithm>
#include <iterator>
#include <limits>
#include <list>
#include <memory>
Expand Down Expand Up @@ -549,6 +550,18 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
opts.gen_generated = true;
} else if (arg == "--swift-implementation-only") {
opts.swift_implementation_only = true;
} else if (arg == "--swift-module-mappings") {
if (++argi >= argc)
Error("missing swift module mappings following: ", true);
opts.swift_module_mappings = argv[argi];
} else if (arg == "--swift-include") {
if (++argi >= argc) Error("missing include following: " + arg, true);
opts.swift_includes.push_back(argv[argi]);
} else if (arg == "--swift-includes") {
if (++argi >= argc) Error("missing include following: " + arg, true);
std::vector<std::string> includes = StringSplit(argv[argi], ',');
std::copy(includes.begin(), includes.end(),
std::back_inserter(opts.swift_includes));
} else if (arg == "--gen-json-emit") {
opts.gen_json_coders = true;
} else if (arg == "--object-prefix") {
Expand Down
91 changes: 87 additions & 4 deletions src/idl_gen_swift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@

#include "idl_gen_swift.h"

#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <iterator>
#include <map>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>

#include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h"
Expand Down Expand Up @@ -148,10 +156,87 @@ static std::string GenArrayMainBody(const std::string &optional) {
optional + " { ";
}

template <typename... Ts>
void Errorf(const std::string &format, Ts... args) {
fprintf(stderr, "[ERROR] Swift: ");
fprintf(stderr, format.c_str(), args...);
fprintf(stderr, "\n");
}

template <typename... Ts>
void Fatalf(const std::string &format, Ts... args) {
fprintf(stderr, "[FATAL] Swift: ");
fprintf(stderr, format.c_str(), args...);
fprintf(stderr, "\n");
exit(1);
}

std::map<std::string, std::string> ReadModules(const std::string &modules) {
std::map<std::string, std::string> module_by_src;
if (modules.empty()) return module_by_src;

std::vector<std::string> entries;
if (modules[0] == '@') {
const char *filename = modules.c_str() + 1;
if (!FileExists(filename)) {
Fatalf("%s does not exist", filename);
}
std::string s;
if (!LoadFile(filename, false, &s)) {
Fatalf("%s cannot be read", filename);
}
entries = StringSplit(s, '\n');
} else {
entries = StringSplit(modules, ',');
}

for (const std::string &entry : entries) {
if (entry.empty()) continue;
size_t pos = entry.find(':');
if (pos == std::string::npos) {
Fatalf("entries must follow \"module:filename.fbs\" format (got %s)",
entry.c_str());
}
module_by_src[entry.substr(0, pos)] = entry.substr(pos + 1);
}
return module_by_src;
}

} // namespace

class SwiftGenerator : public BaseGenerator {
private:
void Import(const std::string &module) {
if (module.empty()) return;
if (parser_.opts.swift_implementation_only) {
code_ += "@_implementationOnly import " + module;
} else {
code_ += "import " + module;
}
}

void ImportDependencies() {
std::set<std::string> deps;
std::copy(parser_.opts.swift_includes.begin(),
parser_.opts.swift_includes.end(),
std::inserter(deps, deps.begin()));

for (const IncludedFile &included_file : parser_.GetIncludedFiles()) {
auto it = module_by_src_.find(included_file.schema_name);
if (it == module_by_src_.end()) {
Errorf("no module is specified for %s",
included_file.schema_name.c_str());
}
deps.insert(it->second);
}

for (const std::string &dep : deps) {
Import(dep);
}
code_ += "";
}

std::map<std::string, std::string> module_by_src_;
CodeWriter code_;
std::unordered_set<std::string> keywords_;
int namespace_depth;
Expand All @@ -162,6 +247,7 @@ class SwiftGenerator : public BaseGenerator {
: BaseGenerator(parser, path, file_name, "", "_", "swift"),
namer_(WithFlagOptions(SwiftDefaultConfig(), parser.opts, path),
SwiftKeywords()) {
module_by_src_ = ReadModules(parser.opts.swift_module_mappings);
namespace_depth = 0;
code_.SetPadding(" ");
}
Expand All @@ -174,10 +260,7 @@ class SwiftGenerator : public BaseGenerator {
code_ += "// swiftlint:disable all";
code_ += "// swiftformat:disable all\n";
if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
if (parser_.opts.swift_implementation_only)
code_ += "@_implementationOnly \\";

code_ += "import FlatBuffers\n";
ImportDependencies();
}

// Generate code for all the enum declarations.
Expand Down
15 changes: 15 additions & 0 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,4 +472,19 @@ std::string ConvertCase(const std::string &input, Case output_case,
}
}

std::vector<std::string> StringSplit(const std::string &s, char delim) {
std::vector<std::string> result;
size_t prev = 0;
while (true) {
size_t pos = s.find(delim, prev);
if (pos == std::string::npos) break;
result.push_back(s.substr(prev, pos));
prev = pos + 1;
}
if (prev <= s.length()) {
result.push_back(s.substr(prev));
}
return result;
}

} // namespace flatbuffers
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,6 @@ public struct Monster: FlatBufferObject, Verifiable {
public var __buffer: ByteBuffer! { return _accessor.bb }
private var _accessor: Table

public static func getRootAsMonster(bb: ByteBuffer) -> Monster { return Monster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }

private init(_ t: Table) { _accessor = t }
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }

Expand Down
Loading
Loading