[Python/JS/TS] Codegen SizeOf method for structs (#6136)
authorAnass Al <anassinator@fb.com>
Mon, 28 Sep 2020 15:54:50 +0000 (08:54 -0700)
committerGitHub <noreply@github.com>
Mon, 28 Sep 2020 15:54:50 +0000 (08:54 -0700)
* [Python] Codegen SizeOf classmethod for structs

This codegens a `SizeOf()` classmethod for all structs since we can't
determine the size of a FlatBuffer generated struct from Python otherwise.

* [JS/TS] Codegen sizeOf static method for structs

This codegens a `sizeOf()` static method for all structs since we can't
determine the size of a FlatBuffer generated struct from JavaScript or
TypeScript otherwise.

14 files changed:
src/idl_gen_js_ts.cpp
src/idl_gen_python.cpp
tests/MyGame/Example/Ability.py
tests/MyGame/Example/ArrayStruct.py
tests/MyGame/Example/NestedStruct.py
tests/MyGame/Example/Test.py
tests/MyGame/Example/Vec3.py
tests/monster_test_generated.js
tests/monster_test_generated.ts
tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
tests/namespace_test/namespace_test1_generated.js
tests/namespace_test/namespace_test1_generated.ts
tests/union_vector/union_vector_generated.js
tests/union_vector/union_vector_generated.ts

index 8be06dff0ff3d3216cdce9e96ab9a35f0476d6b5..02b85bd2f0d941f7f7dc66cb3b20dddd625316fa 100644 (file)
@@ -1795,6 +1795,18 @@ class JsTsGenerator : public BaseGenerator {
       code += "}\n\n";
     }
 
+    // Emit the size of the struct.
+    if (struct_def.fixed) {
+      GenDocComment(code_ptr, GenTypeAnnotation(kReturns, "number", "", false));
+      if (lang_.language == IDLOptions::kTs) {
+        code += "static sizeOf():number {\n";
+      } else {
+        code += object_name + ".sizeOf = function() {\n";
+      }
+      code += "  return " + NumToString(struct_def.bytesize) + ";\n";
+      code += "}\n\n";
+    }
+
     // Emit a factory constructor
     if (struct_def.fixed) {
       std::string annotations =
index c64357e03d9e6b663b4237fd7d9708c311eb8d4a..95b4490af541a745d695ea08b4bf1fc4aeee00ef 100644 (file)
@@ -621,6 +621,16 @@ class PythonGenerator : public BaseGenerator {
     }
   }
 
+  // Generate struct sizeof.
+  void GenStructSizeOf(const StructDef &struct_def, std::string *code_ptr) {
+    auto &code = *code_ptr;
+    code += Indent + "@classmethod\n";
+    code += Indent + "def SizeOf(cls):\n";
+    code +=
+        Indent + Indent + "return " + NumToString(struct_def.bytesize) + "\n";
+    code += "\n";
+  }
+
   // Generate table constructors, conditioned on its members' types.
   void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
     GetStartOfTable(struct_def, code_ptr);
@@ -678,6 +688,9 @@ class PythonGenerator : public BaseGenerator {
         // Generate a special function to test file_identifier
         GenHasFileIdentifier(struct_def, code_ptr);
       }
+    } else {
+      // Generates the SizeOf method for all structs.
+      GenStructSizeOf(struct_def, code_ptr);
     }
     // Generates the Init method that sets the field in a pre-existing
     // accessor object. This is to allow object reuse.
index 2cc916bddae6cbd4bf0c1d0c301f2cecbc7f7df0..e57dfd74f72c4fa69b72bec23544748fd3098185 100644 (file)
@@ -9,6 +9,10 @@ np = import_numpy()
 class Ability(object):
     __slots__ = ['_tab']
 
+    @classmethod
+    def SizeOf(cls):
+        return 8
+
     # Ability
     def Init(self, buf, pos):
         self._tab = flatbuffers.table.Table(buf, pos)
index 50f136df77fea517093755f548734f8eda6c88b7..c80bf6882e11c9c7a8061f4778f16bb04e0efb49 100644 (file)
@@ -9,6 +9,10 @@ np = import_numpy()
 class ArrayStruct(object):
     __slots__ = ['_tab']
 
+    @classmethod
+    def SizeOf(cls):
+        return 160
+
     # ArrayStruct
     def Init(self, buf, pos):
         self._tab = flatbuffers.table.Table(buf, pos)
index a66cee01f205e1d5297a4cd419eff811ee50ddad..a9db014f9acb4c68742271ec33d4c2ef895d2ecf 100644 (file)
@@ -9,6 +9,10 @@ np = import_numpy()
 class NestedStruct(object):
     __slots__ = ['_tab']
 
+    @classmethod
+    def SizeOf(cls):
+        return 32
+
     # NestedStruct
     def Init(self, buf, pos):
         self._tab = flatbuffers.table.Table(buf, pos)
index 576a656e8db048f70df2b39d6544096b7dcb408c..8357ec209c004c9a081f5166c5fc489cc9acc548 100644 (file)
@@ -9,6 +9,10 @@ np = import_numpy()
 class Test(object):
     __slots__ = ['_tab']
 
+    @classmethod
+    def SizeOf(cls):
+        return 4
+
     # Test
     def Init(self, buf, pos):
         self._tab = flatbuffers.table.Table(buf, pos)
index 5c91a7d39193dece9f7dfeb533d5df8bdfb86ae2..69cd511f43bc8615b3be3a22e6b5f52d2aa8260e 100644 (file)
@@ -9,6 +9,10 @@ np = import_numpy()
 class Vec3(object):
     __slots__ = ['_tab']
 
+    @classmethod
+    def SizeOf(cls):
+        return 32
+
     # Vec3
     def Init(self, buf, pos):
         self._tab = flatbuffers.table.Table(buf, pos)
index fedc2c0e13baab37339d3f763827cc02741bdeee..bab85474d64572e7866f0dbee9985df832d8037a 100644 (file)
@@ -342,6 +342,13 @@ MyGame.Example.Test.prototype.mutate_b = function(value) {
   return true;
 };
 
+/**
+ * @returns {number}
+ */
+MyGame.Example.Test.sizeOf = function() {
+  return 4;
+}
+
 /**
  * @param {flatbuffers.Builder} builder
  * @param {number} a
@@ -573,6 +580,13 @@ MyGame.Example.Vec3.prototype.test3 = function(obj) {
   return (obj || new MyGame.Example.Test).__init(this.bb_pos + 26, this.bb);
 };
 
+/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.sizeOf = function() {
+  return 32;
+}
+
 /**
  * @param {flatbuffers.Builder} builder
  * @param {number} x
@@ -659,6 +673,13 @@ MyGame.Example.Ability.prototype.mutate_distance = function(value) {
   return true;
 };
 
+/**
+ * @returns {number}
+ */
+MyGame.Example.Ability.sizeOf = function() {
+  return 8;
+}
+
 /**
  * @param {flatbuffers.Builder} builder
  * @param {number} id
index afdaeabdb59c4f0ec03c9d06bffe7991a9cf6533..9ba7254150d6019401c287b54859545e6a66d2e4 100644 (file)
@@ -376,6 +376,13 @@ mutate_b(value:number):boolean {
   return true;
 };
 
+/**
+ * @returns number
+ */
+static sizeOf():number {
+  return 4;
+}
+
 /**
  * @param flatbuffers.Builder builder
  * @param number a
@@ -668,6 +675,13 @@ test3(obj?:MyGame.Example.Test):MyGame.Example.Test|null {
   return (obj || new MyGame.Example.Test()).__init(this.bb_pos + 26, this.bb!);
 };
 
+/**
+ * @returns number
+ */
+static sizeOf():number {
+  return 32;
+}
+
 /**
  * @param flatbuffers.Builder builder
  * @param number x
@@ -811,6 +825,13 @@ mutate_distance(value:number):boolean {
   return true;
 };
 
+/**
+ * @returns number
+ */
+static sizeOf():number {
+  return 8;
+}
+
 /**
  * @param flatbuffers.Builder builder
  * @param number id
index 9df52bde4834c110d00200232a809cc368d362ea..f49495b62442d6d1bc6cbd8ce049e7b71a0902b8 100644 (file)
@@ -9,6 +9,10 @@ np = import_numpy()
 class StructInNestedNS(object):
     __slots__ = ['_tab']
 
+    @classmethod
+    def SizeOf(cls):
+        return 8
+
     # StructInNestedNS
     def Init(self, buf, pos):
         self._tab = flatbuffers.table.Table(buf, pos)
index fe1c0a754bf8bf265e754870494b05424abc299e..7331f64e4e0fa44db57f1cfea35482b534652845 100644 (file)
@@ -205,6 +205,13 @@ NamespaceA.NamespaceB.StructInNestedNS.getFullyQualifiedName = function() {
   return 'NamespaceA.NamespaceB.StructInNestedNS';
 }
 
+/**
+ * @returns {number}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.sizeOf = function() {
+  return 8;
+}
+
 /**
  * @param {flatbuffers.Builder} builder
  * @param {number} a
index 47f894242203376b213c2192b7c436b37f186c3b..933a43d23359587689d458b792d3d7157f258217 100644 (file)
@@ -204,6 +204,13 @@ static getFullyQualifiedName():string {
   return 'NamespaceA.NamespaceB.StructInNestedNS';
 }
 
+/**
+ * @returns number
+ */
+static sizeOf():number {
+  return 8;
+}
+
 /**
  * @param flatbuffers.Builder builder
  * @param number a
index 01f883c1d4c47a1caae8f6d79b7dba6ae11edc10..9e8b76e64c91e78558bf98a5f6a759990ba70d7a 100644 (file)
@@ -185,6 +185,13 @@ Rapunzel.getFullyQualifiedName = function() {
   return 'Rapunzel';
 }
 
+/**
+ * @returns {number}
+ */
+Rapunzel.sizeOf = function() {
+  return 4;
+}
+
 /**
  * @param {flatbuffers.Builder} builder
  * @param {number} hair_length
@@ -245,6 +252,13 @@ BookReader.getFullyQualifiedName = function() {
   return 'BookReader';
 }
 
+/**
+ * @returns {number}
+ */
+BookReader.sizeOf = function() {
+  return 4;
+}
+
 /**
  * @param {flatbuffers.Builder} builder
  * @param {number} books_read
index eb74fcbc8ff0d4d5ed1e7b40d3acfd2af199fdac..806c07f234fed2d78263ce1a482fa82c21c6fa6f 100644 (file)
@@ -221,6 +221,13 @@ static getFullyQualifiedName():string {
   return 'Rapunzel';
 }
 
+/**
+ * @returns number
+ */
+static sizeOf():number {
+  return 4;
+}
+
 /**
  * @param flatbuffers.Builder builder
  * @param number hair_length
@@ -310,6 +317,13 @@ static getFullyQualifiedName():string {
   return 'BookReader';
 }
 
+/**
+ * @returns number
+ */
+static sizeOf():number {
+  return 4;
+}
+
 /**
  * @param flatbuffers.Builder builder
  * @param number books_read