Fix Rust codegen escaping field in tables. (#7659)

* Fix Rust codegen escaping  field in tables.

* other gencode

* gencode

* removed a debug print

* regen code

Co-authored-by: Casper Neo <cneo@google.com>
Co-authored-by: Derek Bailey <derekbailey@google.com>
This commit is contained in:
Casper
2022-12-15 01:04:57 -05:00
committed by GitHub
parent 9ed76559df
commit a078130c87
7 changed files with 469 additions and 6 deletions

View File

@@ -278,3 +278,122 @@ class KeywordsInTableObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.buffer; return fbBuilder.buffer;
} }
} }
class Table2 {
Table2._(this._bc, this._bcOffset);
factory Table2(List<int> bytes) {
final rootRef = fb.BufferContext.fromBytes(bytes);
return reader.read(rootRef, 0);
}
static const fb.Reader<Table2> reader = _Table2Reader();
final fb.BufferContext _bc;
final int _bcOffset;
KeywordsInUnionTypeId? get typeType => KeywordsInUnionTypeId._createOrNull(const fb.Uint8Reader().vTableGetNullable(_bc, _bcOffset, 4));
dynamic get type {
switch (typeType?.value) {
case 1: return KeywordsInTable.reader.vTableGetNullable(_bc, _bcOffset, 6);
case 2: return KeywordsInTable.reader.vTableGetNullable(_bc, _bcOffset, 6);
default: return null;
}
}
@override
String toString() {
return 'Table2{typeType: ${typeType}, type: ${type}}';
}
Table2T unpack() => Table2T(
typeType: typeType,
type: type);
static int pack(fb.Builder fbBuilder, Table2T? object) {
if (object == null) return 0;
return object.pack(fbBuilder);
}
}
class Table2T implements fb.Packable {
KeywordsInUnionTypeId? typeType;
dynamic type;
Table2T({
this.typeType,
this.type});
@override
int pack(fb.Builder fbBuilder) {
final int? typeOffset = type?.pack(fbBuilder);
fbBuilder.startTable(2);
fbBuilder.addUint8(0, typeType?.value);
fbBuilder.addOffset(1, typeOffset);
return fbBuilder.endTable();
}
@override
String toString() {
return 'Table2T{typeType: ${typeType}, type: ${type}}';
}
}
class _Table2Reader extends fb.TableReader<Table2> {
const _Table2Reader();
@override
Table2 createObject(fb.BufferContext bc, int offset) =>
Table2._(bc, offset);
}
class Table2Builder {
Table2Builder(this.fbBuilder);
final fb.Builder fbBuilder;
void begin() {
fbBuilder.startTable(2);
}
int addTypeType(KeywordsInUnionTypeId? typeType) {
fbBuilder.addUint8(0, typeType?.value);
return fbBuilder.offset;
}
int addTypeOffset(int? offset) {
fbBuilder.addOffset(1, offset);
return fbBuilder.offset;
}
int finish() {
return fbBuilder.endTable();
}
}
class Table2ObjectBuilder extends fb.ObjectBuilder {
final KeywordsInUnionTypeId? _typeType;
final dynamic _type;
Table2ObjectBuilder({
KeywordsInUnionTypeId? typeType,
dynamic type,
})
: _typeType = typeType,
_type = type;
/// Finish building, and store into the [fbBuilder].
@override
int finish(fb.Builder fbBuilder) {
final int? typeOffset = _type?.getOrCreateOffset(fbBuilder);
fbBuilder.startTable(2);
fbBuilder.addUint8(0, _typeType?.value);
fbBuilder.addOffset(1, typeOffset);
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;
}
}

View File

@@ -1629,7 +1629,7 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset)); code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
code_.SetValue("FIELD", namer_.Field(field)); code_.SetValue("FIELD", namer_.Field(field));
code_.SetValue("BLDR_DEF_VAL", GetDefaultValue(field, kBuilder)); code_.SetValue("BLDR_DEF_VAL", GetDefaultValue(field, kBuilder));
code_.SetValue("DISCRIMINANT", namer_.Field(field) + "_type"); code_.SetValue("DISCRIMINANT", namer_.LegacyRustUnionTypeMethod(field));
code_.IncrementIdentLevel(); code_.IncrementIdentLevel();
cb(field); cb(field);
code_.DecrementIdentLevel(); code_.DecrementIdentLevel();
@@ -1747,7 +1747,10 @@ class RustGenerator : public BaseGenerator {
const auto &enum_def = *type.enum_def; const auto &enum_def = *type.enum_def;
code_.SetValue("ENUM_TY", WrapInNameSpace(enum_def)); code_.SetValue("ENUM_TY", WrapInNameSpace(enum_def));
code_.SetValue("NATIVE_ENUM_NAME", NamespacedNativeName(enum_def)); code_.SetValue("NATIVE_ENUM_NAME", NamespacedNativeName(enum_def));
code_ += " let {{FIELD}} = match self.{{FIELD}}_type() {"; code_.SetValue("UNION_TYPE_METHOD",
namer_.LegacyRustUnionTypeMethod(field));
code_ += " let {{FIELD}} = match self.{{UNION_TYPE_METHOD}}() {";
code_ += " {{ENUM_TY}}::NONE => {{NATIVE_ENUM_NAME}}::NONE,"; code_ += " {{ENUM_TY}}::NONE => {{NATIVE_ENUM_NAME}}::NONE,";
ForAllUnionObjectVariantsBesidesNone(enum_def, [&] { ForAllUnionObjectVariantsBesidesNone(enum_def, [&] {
code_ += code_ +=
@@ -1973,10 +1976,12 @@ class RustGenerator : public BaseGenerator {
const EnumDef &union_def = *field.value.type.enum_def; const EnumDef &union_def = *field.value.type.enum_def;
code_.SetValue("UNION_TYPE", WrapInNameSpace(union_def)); code_.SetValue("UNION_TYPE", WrapInNameSpace(union_def));
code_.SetValue("UNION_TYPE_OFFSET_NAME", code_.SetValue("UNION_TYPE_OFFSET_NAME",
namer_.LegacyRustFieldOffsetName(field) + "_TYPE"); namer_.LegacyRustUnionTypeOffsetName(field));
code_.SetValue("UNION_TYPE_METHOD",
namer_.LegacyRustUnionTypeMethod(field));
code_ += code_ +=
"\n .visit_union::<{{UNION_TYPE}}, _>(" "\n .visit_union::<{{UNION_TYPE}}, _>("
"\"{{FIELD}}_type\", Self::{{UNION_TYPE_OFFSET_NAME}}, " "\"{{UNION_TYPE_METHOD}}\", Self::{{UNION_TYPE_OFFSET_NAME}}, "
"\"{{FIELD}}\", Self::{{OFFSET_NAME}}, {{IS_REQ}}, " "\"{{FIELD}}\", Self::{{OFFSET_NAME}}, {{IS_REQ}}, "
"|key, v, pos| {"; "|key, v, pos| {";
code_ += " match key {"; code_ += " match key {";
@@ -2045,8 +2050,10 @@ class RustGenerator : public BaseGenerator {
const auto &enum_def = *type.enum_def; const auto &enum_def = *type.enum_def;
code_.SetValue("ENUM_TY", WrapInNameSpace(enum_def)); code_.SetValue("ENUM_TY", WrapInNameSpace(enum_def));
code_.SetValue("FIELD", namer_.Field(field)); code_.SetValue("FIELD", namer_.Field(field));
code_.SetValue("UNION_TYPE_METHOD",
namer_.LegacyRustUnionTypeMethod(field));
code_ += " match self.{{FIELD}}_type() {"; code_ += " match self.{{UNION_TYPE_METHOD}}() {";
code_ += " {{ENUM_TY}}::NONE => (),"; code_ += " {{ENUM_TY}}::NONE => (),";
ForAllUnionObjectVariantsBesidesNone(enum_def, [&] { ForAllUnionObjectVariantsBesidesNone(enum_def, [&] {
code_.SetValue("FIELD", namer_.Field(field)); code_.SetValue("FIELD", namer_.Field(field));
@@ -2255,8 +2262,9 @@ class RustGenerator : public BaseGenerator {
case ftUnionValue: { case ftUnionValue: {
code_.SetValue("ENUM_METHOD", code_.SetValue("ENUM_METHOD",
namer_.Method(*field.value.type.enum_def)); namer_.Method(*field.value.type.enum_def));
code_.SetValue("DISCRIMINANT", namer_.LegacyRustUnionTypeMethod(field));
code_ += code_ +=
" let {{FIELD}}_type = " " let {{DISCRIMINANT}} = "
"self.{{FIELD}}.{{ENUM_METHOD}}_type();"; "self.{{FIELD}}.{{ENUM_METHOD}}_type();";
code_ += " let {{FIELD}} = self.{{FIELD}}.pack(_fbb);"; code_ += " let {{FIELD}} = self.{{FIELD}}.pack(_fbb);";
return; return;

View File

@@ -102,6 +102,10 @@ class IdlNamer : public Namer {
std::string LegacyRustFieldOffsetName(const FieldDef &field) const { std::string LegacyRustFieldOffsetName(const FieldDef &field) const {
return "VT_" + ConvertCase(EscapeKeyword(field.name), Case::kAllUpper); return "VT_" + ConvertCase(EscapeKeyword(field.name), Case::kAllUpper);
} }
std::string LegacyRustUnionTypeOffsetName(const FieldDef &field) const {
return "VT_" + ConvertCase(EscapeKeyword(field.name + "_type"), Case::kAllUpper);
}
std::string LegacySwiftVariant(const EnumVal &ev) const { std::string LegacySwiftVariant(const EnumVal &ev) const {
auto name = ev.name; auto name = ev.name;
@@ -140,6 +144,11 @@ class IdlNamer : public Namer {
return "mutate_" + d.name; return "mutate_" + d.name;
} }
std::string LegacyRustUnionTypeMethod(const FieldDef &d) {
// assert d is a union
return Method(d.name + "_type");
}
private: private:
std::string NamespacedString(const struct Namespace *ns, std::string NamespacedString(const struct Namespace *ns,
const std::string &str) const { const std::string &str) const {

View File

@@ -0,0 +1,94 @@
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
namespace KeywordTest
{
using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
public struct Table2 : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_22_12_06(); }
public static Table2 GetRootAsTable2(ByteBuffer _bb) { return GetRootAsTable2(_bb, new Table2()); }
public static Table2 GetRootAsTable2(ByteBuffer _bb, Table2 obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Table2 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public KeywordTest.KeywordsInUnion TypeType { get { int o = __p.__offset(4); return o != 0 ? (KeywordTest.KeywordsInUnion)__p.bb.Get(o + __p.bb_pos) : KeywordTest.KeywordsInUnion.NONE; } }
public TTable? Type<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(6); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
public KeywordTest.KeywordsInTable TypeAsstatic() { return Type<KeywordTest.KeywordsInTable>().Value; }
public KeywordTest.KeywordsInTable TypeAsinternal() { return Type<KeywordTest.KeywordsInTable>().Value; }
public static Offset<KeywordTest.Table2> CreateTable2(FlatBufferBuilder builder,
KeywordTest.KeywordsInUnion type_type = KeywordTest.KeywordsInUnion.NONE,
int typeOffset = 0) {
builder.StartTable(2);
Table2.AddType(builder, typeOffset);
Table2.AddTypeType(builder, type_type);
return Table2.EndTable2(builder);
}
public static void StartTable2(FlatBufferBuilder builder) { builder.StartTable(2); }
public static void AddTypeType(FlatBufferBuilder builder, KeywordTest.KeywordsInUnion typeType) { builder.AddByte(0, (byte)typeType, 0); }
public static void AddType(FlatBufferBuilder builder, int typeOffset) { builder.AddOffset(1, typeOffset, 0); }
public static Offset<KeywordTest.Table2> EndTable2(FlatBufferBuilder builder) {
int o = builder.EndTable();
return new Offset<KeywordTest.Table2>(o);
}
public Table2T UnPack() {
var _o = new Table2T();
this.UnPackTo(_o);
return _o;
}
public void UnPackTo(Table2T _o) {
_o.Type = new KeywordTest.KeywordsInUnionUnion();
_o.Type.Type = this.TypeType;
switch (this.TypeType) {
default: break;
case KeywordTest.KeywordsInUnion.static:
_o.Type.Value = this.Type<KeywordTest.KeywordsInTable>().HasValue ? this.Type<KeywordTest.KeywordsInTable>().Value.UnPack() : null;
break;
case KeywordTest.KeywordsInUnion.internal:
_o.Type.Value = this.Type<KeywordTest.KeywordsInTable>().HasValue ? this.Type<KeywordTest.KeywordsInTable>().Value.UnPack() : null;
break;
}
}
public static Offset<KeywordTest.Table2> Pack(FlatBufferBuilder builder, Table2T _o) {
if (_o == null) return default(Offset<KeywordTest.Table2>);
var _type_type = _o.Type == null ? KeywordTest.KeywordsInUnion.NONE : _o.Type.Type;
var _type = _o.Type == null ? 0 : KeywordTest.KeywordsInUnionUnion.Pack(builder, _o.Type);
return CreateTable2(
builder,
_type_type,
_type);
}
}
public class Table2T
{
[Newtonsoft.Json.JsonProperty("type_type")]
private KeywordTest.KeywordsInUnion TypeType {
get {
return this.Type != null ? this.Type.Type : KeywordTest.KeywordsInUnion.NONE;
}
set {
this.Type = new KeywordTest.KeywordsInUnionUnion();
this.Type.Type = value;
}
}
[Newtonsoft.Json.JsonProperty("type")]
[Newtonsoft.Json.JsonConverter(typeof(KeywordTest.KeywordsInUnionUnion_JsonConverter))]
public KeywordTest.KeywordsInUnionUnion Type { get; set; }
public Table2T() {
this.Type = null;
}
}
}

View File

@@ -15,3 +15,7 @@ union KeywordsInUnion {
static: KeywordsInTable, static: KeywordsInTable,
internal: KeywordsInTable, internal: KeywordsInTable,
} }
table Table2 {
type: KeywordsInUnion;
}

View File

@@ -0,0 +1,227 @@
// automatically generated by the FlatBuffers compiler, do not modify
// @generated
extern crate alloc;
extern crate flatbuffers;
use alloc::boxed::Box;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use core::mem;
use core::cmp::Ordering;
use self::flatbuffers::{EndianScalar, Follow};
use super::*;
pub enum Table2Offset {}
#[derive(Copy, Clone, PartialEq)]
pub struct Table2<'a> {
pub _tab: flatbuffers::Table<'a>,
}
impl<'a> flatbuffers::Follow<'a> for Table2<'a> {
type Inner = Table2<'a>;
#[inline]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Self { _tab: flatbuffers::Table::new(buf, loc) }
}
}
impl<'a> Table2<'a> {
pub const VT_TYPE_TYPE: flatbuffers::VOffsetT = 4;
pub const VT_TYPE_: flatbuffers::VOffsetT = 6;
pub const fn get_fully_qualified_name() -> &'static str {
"KeywordTest.Table2"
}
#[inline]
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
Table2 { _tab: table }
}
#[allow(unused_mut)]
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
args: &'args Table2Args
) -> flatbuffers::WIPOffset<Table2<'bldr>> {
let mut builder = Table2Builder::new(_fbb);
if let Some(x) = args.type_ { builder.add_type_(x); }
builder.add_type_type(args.type_type);
builder.finish()
}
pub fn unpack(&self) -> Table2T {
let type_ = match self.type_type() {
KeywordsInUnion::NONE => KeywordsInUnionT::NONE,
KeywordsInUnion::static_ => KeywordsInUnionT::Static_(Box::new(
self.type__as_static_()
.expect("Invalid union table, expected `KeywordsInUnion::static_`.")
.unpack()
)),
KeywordsInUnion::internal => KeywordsInUnionT::Internal(Box::new(
self.type__as_internal()
.expect("Invalid union table, expected `KeywordsInUnion::internal`.")
.unpack()
)),
_ => KeywordsInUnionT::NONE,
};
Table2T {
type_,
}
}
#[inline]
pub fn type_type(&self) -> KeywordsInUnion {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<KeywordsInUnion>(Table2::VT_TYPE_TYPE, Some(KeywordsInUnion::NONE)).unwrap()}
}
#[inline]
pub fn type_(&self) -> Option<flatbuffers::Table<'a>> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Table<'a>>>(Table2::VT_TYPE_, None)}
}
#[inline]
#[allow(non_snake_case)]
pub fn type__as_static_(&self) -> Option<KeywordsInTable<'a>> {
if self.type_type() == KeywordsInUnion::static_ {
self.type_().map(|t| {
// Safety:
// Created from a valid Table for this object
// Which contains a valid union in this slot
unsafe { KeywordsInTable::init_from_table(t) }
})
} else {
None
}
}
#[inline]
#[allow(non_snake_case)]
pub fn type__as_internal(&self) -> Option<KeywordsInTable<'a>> {
if self.type_type() == KeywordsInUnion::internal {
self.type_().map(|t| {
// Safety:
// Created from a valid Table for this object
// Which contains a valid union in this slot
unsafe { KeywordsInTable::init_from_table(t) }
})
} else {
None
}
}
}
impl flatbuffers::Verifiable for Table2<'_> {
#[inline]
fn run_verifier(
v: &mut flatbuffers::Verifier, pos: usize
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
use self::flatbuffers::Verifiable;
v.visit_table(pos)?
.visit_union::<KeywordsInUnion, _>("type_type", Self::VT_TYPE_TYPE, "type_", Self::VT_TYPE_, false, |key, v, pos| {
match key {
KeywordsInUnion::static_ => v.verify_union_variant::<flatbuffers::ForwardsUOffset<KeywordsInTable>>("KeywordsInUnion::static_", pos),
KeywordsInUnion::internal => v.verify_union_variant::<flatbuffers::ForwardsUOffset<KeywordsInTable>>("KeywordsInUnion::internal", pos),
_ => Ok(()),
}
})?
.finish();
Ok(())
}
}
pub struct Table2Args {
pub type_type: KeywordsInUnion,
pub type_: Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>,
}
impl<'a> Default for Table2Args {
#[inline]
fn default() -> Self {
Table2Args {
type_type: KeywordsInUnion::NONE,
type_: None,
}
}
}
pub struct Table2Builder<'a: 'b, 'b> {
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
}
impl<'a: 'b, 'b> Table2Builder<'a, 'b> {
#[inline]
pub fn add_type_type(&mut self, type_type: KeywordsInUnion) {
self.fbb_.push_slot::<KeywordsInUnion>(Table2::VT_TYPE_TYPE, type_type, KeywordsInUnion::NONE);
}
#[inline]
pub fn add_type_(&mut self, type_: flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>) {
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Table2::VT_TYPE_, type_);
}
#[inline]
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> Table2Builder<'a, 'b> {
let start = _fbb.start_table();
Table2Builder {
fbb_: _fbb,
start_: start,
}
}
#[inline]
pub fn finish(self) -> flatbuffers::WIPOffset<Table2<'a>> {
let o = self.fbb_.end_table(self.start_);
flatbuffers::WIPOffset::new(o.value())
}
}
impl core::fmt::Debug for Table2<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut ds = f.debug_struct("Table2");
ds.field("type_type", &self.type_type());
match self.type_type() {
KeywordsInUnion::static_ => {
if let Some(x) = self.type__as_static_() {
ds.field("type_", &x)
} else {
ds.field("type_", &"InvalidFlatbuffer: Union discriminant does not match value.")
}
},
KeywordsInUnion::internal => {
if let Some(x) = self.type__as_internal() {
ds.field("type_", &x)
} else {
ds.field("type_", &"InvalidFlatbuffer: Union discriminant does not match value.")
}
},
_ => {
let x: Option<()> = None;
ds.field("type_", &x)
},
};
ds.finish()
}
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub struct Table2T {
pub type_: KeywordsInUnionT,
}
impl Default for Table2T {
fn default() -> Self {
Self {
type_: KeywordsInUnionT::NONE,
}
}
}
impl Table2T {
pub fn pack<'b>(
&self,
_fbb: &mut flatbuffers::FlatBufferBuilder<'b>
) -> flatbuffers::WIPOffset<Table2<'b>> {
let type_type = self.type_.keywords_in_union_type();
let type_ = self.type_.pack(_fbb);
Table2::create(_fbb, &Table2Args{
type_type,
type_,
})
}
}

View File

@@ -10,4 +10,6 @@ pub mod keyword_test {
pub use self::keywords_in_union_generated::*; pub use self::keywords_in_union_generated::*;
mod keywords_in_table_generated; mod keywords_in_table_generated;
pub use self::keywords_in_table_generated::*; pub use self::keywords_in_table_generated::*;
mod table_2_generated;
pub use self::table_2_generated::*;
} // keyword_test } // keyword_test