Feature: lua now file_ident aware (#8850)

* lua code not file ident aware

* update genned code

* make mac happy

* pr comments
diff --git a/lua/flatbuffers/builder.lua b/lua/flatbuffers/builder.lua
index 25e0032..0f1ac79 100644
--- a/lua/flatbuffers/builder.lua
+++ b/lua/flatbuffers/builder.lua
@@ -296,25 +296,62 @@
     self.currentVTable[slotnum + 1] = self:Offset()
 end
 
-local function finish(self, rootTable, sizePrefix)
+local function finish(self, rootTable, sizePrefix, fileIdentifier)
     UOffsetT:EnforceNumber(rootTable)
-    self:Prep(self.minalign, sizePrefix and 8 or 4)
-    self:PrependUOffsetTRelative(rootTable)
+    local hasFid = fileIdentifier ~= nil
+    if hasFid then
+        assert(#fileIdentifier == 4, "File identifier must be exactly 4 bytes")
+    end
+
+    local fid_byte_count = (hasFid and 4 or 0)
+
+    -- alignment:
+    -- root offset (4)
+    -- optional file id (4)
+    -- optional size prefix (4)
+    self:Prep(
+        self.minalign,
+        (sizePrefix and 4 or 0) +
+        4 +
+        fid_byte_count
+    )
+
+    -- root offset (points past file identifier if present)
+    self:PrependUOffsetTRelative(rootTable + fid_byte_count)
+
+    -- file identifier
+    if hasFid then
+        for i = 4, 1, -1 do
+            self:PrependByte(string.byte(fileIdentifier, i))
+        end
+    end
+
+    -- size prefix
     if sizePrefix then
         local size = self.bytes.size - self.head
         Int32:EnforceNumber(size)
         self:PrependInt32(size)
     end
+
     self.finished = true
     return self.head
 end
 
+
 function mt:Finish(rootTable)
-    return finish(self, rootTable, false)
+    return finish(self, rootTable, false, nil)
 end
 
 function mt:FinishSizePrefixed(rootTable)
-    return finish(self, rootTable, true)
+    return finish(self, rootTable, true, nil)
+end
+
+function mt:FinishWithIdentifier(rootTable, fileIdentifier)
+    return finish(self, rootTable, false, fileIdentifier)
+end
+
+function mt:FinishSizePrefixedWithIdentifier(rootTable, fileIdentifier)
+    return finish(self, rootTable, true, fileIdentifier)
 end
 
 function mt:Prepend(flags, off)
diff --git a/src/bfbs_gen_lua.cpp b/src/bfbs_gen_lua.cpp
index 4507fe6..5e8def2 100644
--- a/src/bfbs_gen_lua.cpp
+++ b/src/bfbs_gen_lua.cpp
@@ -195,6 +195,13 @@
       code += "\n";
 
       if (object == root_object) {
+        // emit file identifier if present
+        const auto ident = schema_->file_ident();
+        if (ident && ident->size() == 4) {
+          code += "local FileIdentifier = \"" + ident->str() + "\"\n";
+          code += "\n";
+        }
+
         code += "function " + object_name + ".GetRootAs" + object_name +
                 "(buf, offset)\n";
         code += "  if type(buf) == \"string\" then\n";
@@ -455,6 +462,34 @@
         code += "  return builder:EndObject()\n";
         code += "end\n";
         code += "\n";
+
+        if (object == root_object) {
+          code += "function " + object_name + ".Finish" + object_name +
+                  "Buffer(builder, offset)\n";
+          // emit file identifier if present
+          const auto ident = schema_->file_ident();
+          if (ident && ident->size() == 4) {
+            code += "  builder:FinishWithIdentifier(offset, FileIdentifier)\n";
+          } else {
+            code += "  builder:Finish(offset)\n";
+          }
+          code += "end\n";
+          code += "\n";
+
+          // size prefixed option
+          code += "function " + object_name + ".FinishSizePrefixed" +
+                  object_name + "Buffer(builder, offset)\n";
+          // emit file identifier if present
+          if (ident && ident->size() == 4) {
+            code +=
+                "  builder:FinishSizePrefixedWithIdentifier(offset, "
+                "FileIdentifier)\n";
+          } else {
+            code += "  builder:FinishSizePrefixed(offset)\n";
+          }
+          code += "end\n";
+          code += "\n";
+        }
       }
 
       EmitCodeBlock(code, object_name, ns, object->declaration_file()->str());
diff --git a/tests/MyGame/Example/Monster.lua b/tests/MyGame/Example/Monster.lua
index 851ae03..e39d172 100644
--- a/tests/MyGame/Example/Monster.lua
+++ b/tests/MyGame/Example/Monster.lua
@@ -28,6 +28,8 @@
   return o
 end
 
+local FileIdentifier = "MONS"
+
 function Monster.GetRootAsMonster(buf, offset)
   if type(buf) == "string" then
     buf = flatbuffers.binaryArray.New(buf)
@@ -1099,4 +1101,12 @@
   return builder:EndObject()
 end
 
+function Monster.FinishMonsterBuffer(builder, offset)
+  builder:FinishWithIdentifier(offset, FileIdentifier)
+end
+
+function Monster.FinishSizePrefixedMonsterBuffer(builder, offset)
+  builder:FinishSizePrefixedWithIdentifier(offset, FileIdentifier)
+end
+
 return Monster
\ No newline at end of file