THRIFT-4086: Add missing calls to get_true_type when generating validator + metadata code

Client: java
diff --git a/lib/java/src/test/java/org/apache/thrift/TestStructOrder.java b/lib/java/src/test/java/org/apache/thrift/TestStructOrder.java
new file mode 100644
index 0000000..dd67d9b
--- /dev/null
+++ b/lib/java/src/test/java/org/apache/thrift/TestStructOrder.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.thrift;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.*;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+// Tests that declaring structs in different order (esp. when they reference each other) generates
+// identical code
+public class TestStructOrder {
+
+  @Test
+  public void testStructOrder() throws Exception {
+    List<String> filenames = Arrays.asList("Parent.java", "Child.java");
+
+    for (String fn : filenames) {
+      String fnA = "struct-order-test/a/" + fn;
+      String fnB = "struct-order-test/b/" + fn;
+
+      try (InputStream isA = TestStructOrder.class.getClassLoader().getResourceAsStream(fnA);
+          InputStream isB = TestStructOrder.class.getClassLoader().getResourceAsStream(fnB)) {
+
+        assertNotNull(isA, "Resource not found: " + fnA);
+        assertNotNull(isB, "Resource not found: " + fnB);
+
+        int hashA = Arrays.hashCode(readAllBytes(isA));
+        assertEquals(
+            hashA,
+            Arrays.hashCode(readAllBytes(isB)),
+            String.format("Generated Java files %s and %s differ", fnA, fnB));
+      }
+    }
+  }
+
+  // TODO Use InputStream.readAllBytes post-Java8
+  private byte[] readAllBytes(InputStream is) throws IOException {
+    ByteArrayOutputStream os = new ByteArrayOutputStream();
+    byte[] buff = new byte[1024];
+    int bytesRead;
+    while ((bytesRead = is.read(buff, 0, buff.length)) != -1) {
+      os.write(buff, 0, bytesRead);
+    }
+    return os.toByteArray();
+  }
+}
diff --git a/lib/java/src/test/resources/JavaStructOrderA.thrift b/lib/java/src/test/resources/JavaStructOrderA.thrift
new file mode 100644
index 0000000..bac5209
--- /dev/null
+++ b/lib/java/src/test/resources/JavaStructOrderA.thrift
@@ -0,0 +1,9 @@
+// Define Parent, then Child. No forward declarations.
+struct Parent {
+    1: required string Name
+}
+
+struct Child {
+    1: required string Name
+    2: required Parent Parent
+}
diff --git a/lib/java/src/test/resources/JavaStructOrderB.thrift b/lib/java/src/test/resources/JavaStructOrderB.thrift
new file mode 100644
index 0000000..aa2afea
--- /dev/null
+++ b/lib/java/src/test/resources/JavaStructOrderB.thrift
@@ -0,0 +1,10 @@
+// Define Child, then Parent. Parent is a forward declaration and was problematic for our Java compiler before
+// fixing THRIFT-4086: Java compiler generates different meta data depending on order of structures in file
+struct Child {
+    1: required string Name
+    2: required Parent Parent
+}
+
+struct Parent {
+    1: required string Name
+}