Initial tests for protobuf lite

Bug: 134709054, 112437944
Change-Id: Id03026156cc364f5174c12479c43913d8275968e
diff --git a/.gitignore b/.gitignore
index 191dbbd..e5f3042 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,6 +73,10 @@
 !third_party/proguard/*.sha1
 third_party/proguardsettings.tar.gz
 third_party/proguardsettings/
+third_party/proto.tar.gz
+third_party/proto/
+third_party/protobuf-lite.tar.gz
+third_party/protobuf-lite/
 third_party/youtube/*
 !third_party/youtube/*sha1
 third_party/jctf
diff --git a/build.gradle b/build.gradle
index 52abc60..7a31aee 100644
--- a/build.gradle
+++ b/build.gradle
@@ -151,6 +151,14 @@
         }
         output.resourcesDir = 'build/classes/examplesAndroidP'
     }
+    examplesProto {
+        java {
+            srcDirs = ['src/test/examplesProto']
+        }
+        compileClasspath = files(file("build/generated/test/proto").listFiles())
+        compileClasspath += files("third_party/protobuf-lite/libprotobuf_lite.jar")
+        output.resourcesDir = 'build/classes/examplesProto'
+    }
     jctfCommon {
         java {
             srcDirs = [
@@ -382,6 +390,8 @@
         "photos/2017-06-06",
         "proguard/proguard_internal_159423826",
         "proguardsettings",
+        "proto",
+        "protobuf-lite",
         "youtube/youtube.android_12.10",
         "youtube/youtube.android_12.17",
         "youtube/youtube.android_12.22",
@@ -1074,6 +1084,55 @@
     }
 }
 
+task buildProtoGeneratedSources {
+    def examplesProtoDir = file("src/test/examplesProto")
+    examplesProtoDir.eachDir { dir ->
+        def name = dir.getName()
+        task "compile_proto_generated_source_${name}"(type: JavaCompile) {
+            source = {
+                file('third_party/proto').listFiles()
+                        .findAll { it.name.startsWith(name) && it.name.endsWith('-src.jar') }
+                        .collect { zipTree(it) }
+            }
+            destinationDir = file("build/generated/test/proto/${name}_classes")
+            classpath = files("third_party/protobuf-lite/libprotobuf_lite.jar")
+            sourceCompatibility = JavaVersion.VERSION_1_8
+            targetCompatibility = JavaVersion.VERSION_1_8
+        }
+        task "jar_proto_generated_source_${name}"(type: Jar, dependsOn: "compile_proto_generated_source_${name}") {
+            archiveName = "${name}.jar"
+            destinationDir = file("build/generated/test/proto")
+            from "build/generated/test/proto/${name}_classes"
+            include "/**/*.class"
+        }
+        dependsOn "jar_proto_generated_source_${name}"
+    }
+}
+
+task buildExamplesProto {
+    def examplesProtoDir = file("src/test/examplesProto")
+    def examplesProtoOutputDir = file("build/test/examplesProto");
+    dependsOn buildProtoGeneratedSources
+    task "compile_examples_proto"(type: JavaCompile) {
+        source = fileTree(dir: examplesProtoDir, include: "**/*.java")
+        destinationDir = file("build/test/examplesProto/classes")
+        classpath = files(file("build/generated/test/proto").listFiles())
+        classpath += files("third_party/protobuf-lite/libprotobuf_lite.jar")
+        sourceCompatibility = JavaVersion.VERSION_1_8
+        targetCompatibility = JavaVersion.VERSION_1_8
+    }
+    examplesProtoDir.eachDir { dir ->
+        def name = dir.getName()
+        task "jar_examples_proto_${name}"(type: Jar, dependsOn: "compile_examples_proto") {
+            archiveName = "${name}.jar"
+            destinationDir = examplesProtoOutputDir
+            from "build/test/examplesProto/classes"
+            include name + "/**/*.class"
+        }
+        dependsOn "jar_examples_proto_${name}"
+    }
+}
+
 // Proto lite generated code yields warnings when compiling with javac.
 // We change the options passed to javac to ignore it.
 compileExamplesJava.options.compilerArgs = ["-Xlint:none"]
@@ -1690,6 +1749,8 @@
     }
     if (project.hasProperty('no_internal')) {
         exclude "com/android/tools/r8/internal/**"
+    } else {
+        dependsOn buildExamplesProto
     }
     if (project.hasProperty('only_internal')) {
         include "com/android/tools/r8/internal/**"
diff --git a/src/test/examplesProto/proto2/TestClass.java b/src/test/examplesProto/proto2/TestClass.java
new file mode 100644
index 0000000..64c3ba7
--- /dev/null
+++ b/src/test/examplesProto/proto2/TestClass.java
@@ -0,0 +1,195 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package proto2;
+
+import com.android.tools.r8.proto2.Graph.IsExtendedWithOptional;
+import com.android.tools.r8.proto2.Graph.IsExtendedWithRequiredField;
+import com.android.tools.r8.proto2.Graph.IsRepeatedlyExtendedWithRequiredField;
+import com.android.tools.r8.proto2.Graph.UsedRoot;
+import com.android.tools.r8.proto2.Shrinking.ContainsFlaggedOffField;
+import com.android.tools.r8.proto2.Shrinking.HasFlaggedOffExtension;
+import com.android.tools.r8.proto2.Shrinking.PartiallyUsed;
+import com.android.tools.r8.proto2.Shrinking.PartiallyUsedWithExtension;
+import com.android.tools.r8.proto2.Shrinking.UsedViaHazzer;
+import com.android.tools.r8.proto2.Shrinking.UsedViaOneofCase;
+import com.android.tools.r8.proto2.Shrinking.UsesOnlyRepeatedFields;
+import com.android.tools.r8.proto2.TestProto.Primitives;
+import com.google.protobuf.ExtensionRegistryLite;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.WireFormat;
+import java.nio.ByteBuffer;
+
+public class TestClass {
+
+  public static void main(String[] args) {
+    roundtrip();
+    partiallyUsed_proto2();
+    usedViaHazzer();
+    usedViaOneofCase();
+    usesOnlyRepeatedFields();
+    containsFlaggedOffField();
+    hasFlaggedOffExtension();
+    useOneExtension();
+    keepMapAndRequiredFields();
+  }
+
+  // A protobuf payload indicating that varint field 1 is set to 42.
+  // See https://developers.google.com/protocol-buffers/docs/encoding
+  //
+  // Since serialization and deserialization use the same schema (which we're modifying), testing
+  // against wire-format data is preferred.
+  private static final byte[] FIELD1_SET_TO_42 =
+      new byte[] {(1 << 3) | WireFormat.WIRETYPE_VARINT, 42};
+
+  // A protobuf payload indicating that field 10 is a message whose field 1 is set to 42.
+  private static final byte[] MESSAGE10_WITH_FIELD1_SET_TO_42 =
+      ByteBuffer.allocate(4)
+          .put(
+              new byte[] {
+                (10 << 3) | WireFormat.WIRETYPE_LENGTH_DELIMITED, (byte) FIELD1_SET_TO_42.length
+              })
+          .put(FIELD1_SET_TO_42)
+          .array();
+
+  // smoke test
+  static void roundtrip() {
+    System.out.println("--- roundtrip ---");
+    Primitives primitives =
+        Primitives.newBuilder()
+            .setFooInt32(123)
+            .setOneofString("asdf")
+            .setBarInt64(Long.MAX_VALUE)
+            .setQuxString("qwerty")
+            .build();
+
+    Primitives roundtripped;
+    try {
+      roundtripped = Primitives.parseFrom(primitives.toByteArray());
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+
+    System.out.println(roundtripped.equals(primitives));
+    System.out.println(roundtripped.getFooInt32());
+    System.out.println(roundtripped.getOneofString());
+    System.out.println(roundtripped.getBarInt64());
+    System.out.println(roundtripped.getQuxString());
+  }
+
+  static void partiallyUsed_proto2() {
+    System.out.println("--- partiallyUsed_proto2 ---");
+    PartiallyUsed pu;
+    try {
+      pu = PartiallyUsed.parseFrom(FIELD1_SET_TO_42);
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+    System.out.println(pu.hasUsed());
+    System.out.println(pu.getUsed());
+  }
+
+  static void usedViaHazzer() {
+    System.out.println("--- usedViaHazzer ---");
+    UsedViaHazzer uvh;
+    try {
+      uvh = UsedViaHazzer.parseFrom(FIELD1_SET_TO_42);
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+    System.out.println(uvh.hasUsed());
+  }
+
+  static void usedViaOneofCase() {
+    System.out.println("--- usedViaOneofCase ---");
+    UsedViaOneofCase msg;
+    try {
+      msg = UsedViaOneofCase.parseFrom(FIELD1_SET_TO_42);
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+    System.out.println(msg.hasUsed());
+  }
+
+  static void usesOnlyRepeatedFields() {
+    System.out.println("--- usesOnlyRepeatedFields ---");
+    UsesOnlyRepeatedFields msg;
+    try {
+      msg = UsesOnlyRepeatedFields.parseFrom(FIELD1_SET_TO_42);
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+    System.out.println(msg.getUsedCount());
+  }
+
+  static void containsFlaggedOffField() {
+    System.out.println("--- containsFlaggedOffField ---");
+    ContainsFlaggedOffField.Builder builder = ContainsFlaggedOffField.newBuilder();
+    if (alwaysFalse()) {
+      builder.setConditionallyUsed(1);
+    }
+    System.out.println(builder.build().getSerializedSize());
+  }
+
+  static void hasFlaggedOffExtension() {
+    System.out.println("--- hasFlaggedOffExtension ---");
+    HasFlaggedOffExtension msg;
+    try {
+      msg =
+          HasFlaggedOffExtension.parseFrom(
+              MESSAGE10_WITH_FIELD1_SET_TO_42, ExtensionRegistryLite.getGeneratedRegistry());
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+    if (alwaysFalse()) {
+      System.out.println(msg.getExtension(HasFlaggedOffExtension.Ext.ext).getX());
+    }
+    System.out.println(msg.getSerializedSize());
+  }
+
+  static boolean alwaysFalse() {
+    return false;
+  }
+
+  static void useOneExtension() {
+    System.out.println("--- useOneExtension ---");
+
+    PartiallyUsedWithExtension msg;
+    try {
+      msg =
+          PartiallyUsedWithExtension.parseFrom(
+              MESSAGE10_WITH_FIELD1_SET_TO_42, ExtensionRegistryLite.getGeneratedRegistry());
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+
+    PartiallyUsedWithExtension.ExtA ext = msg.getExtension(PartiallyUsedWithExtension.ExtA.extA);
+    System.out.println(ext.getX());
+  }
+
+  static void keepMapAndRequiredFields() {
+    System.out.println("--- keepMapAndRequiredFields ---");
+
+    UsedRoot msg;
+    try {
+      msg = UsedRoot.parseFrom(new byte[0], ExtensionRegistryLite.getGeneratedRegistry());
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+    System.out.println(msg.isInitialized());
+    // Force extension edges to be kept.  This test is for verifying that we keep *fields* which
+    // lead to extensions with required fields.  b/123031088 is for keeping the extensions.
+    System.out.println(IsExtendedWithRequiredField.Ext.ext.getNumber());
+    System.out.println(IsRepeatedlyExtendedWithRequiredField.Ext.ext.getNumber());
+    System.out.println(IsExtendedWithOptional.Ext.ext.getNumber());
+  }
+}
diff --git a/src/test/examplesProto/proto3/TestClass.java b/src/test/examplesProto/proto3/TestClass.java
new file mode 100644
index 0000000..1eec5d8
--- /dev/null
+++ b/src/test/examplesProto/proto3/TestClass.java
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package proto3;
+
+import com.android.tools.r8.proto3.Shrinking.PartiallyUsed;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.WireFormat;
+
+public class TestClass {
+
+  public static void main(String[] args) {
+    partiallyUsed_proto3();
+  }
+
+  // A protobuf payload indicating that varint field 1 is set to 42.
+  // See https://developers.google.com/protocol-buffers/docs/encoding
+  //
+  // Since serialization and deserialization use the same schema (which we're modifying), testing
+  // against wire-format data is preferred.
+  private static final byte[] FIELD1_SET_TO_42 =
+      new byte[] {(1 << 3) | WireFormat.WIRETYPE_VARINT, 42};
+
+  static void partiallyUsed_proto3() {
+    System.out.println("--- partiallyUsed_proto3 ---");
+    PartiallyUsed pu;
+    try {
+      pu = PartiallyUsed.parseFrom(FIELD1_SET_TO_42);
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+    System.out.println(pu.getUsed());
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 1d9fd27..9349161 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -79,7 +79,9 @@
 public class ToolHelper {
 
   public static final String BUILD_DIR = "build/";
+  public static final String GENERATED_TEST_BUILD_DIR = BUILD_DIR + "generated/test/";
   public static final String LIBS_DIR = BUILD_DIR + "libs/";
+  public static final String THIRD_PARTY_DIR = "third_party/";
   public static final String TOOLS_DIR = "tools/";
   public static final String TESTS_DIR = "src/test/";
   public static final String EXAMPLES_DIR = TESTS_DIR + "examples/";
@@ -99,6 +101,8 @@
   public static final String EXAMPLES_JAVA9_BUILD_DIR = TESTS_BUILD_DIR + "examplesJava9/";
   public static final String EXAMPLES_JAVA11_JAR_DIR = TESTS_BUILD_DIR + "examplesJava11/";
   public static final String EXAMPLES_JAVA11_BUILD_DIR = BUILD_DIR + "classes/java/examplesJava11/";
+  public static final String EXAMPLES_PROTO_BUILD_DIR = TESTS_BUILD_DIR + "examplesProto/";
+  public static final String GENERATED_PROTO_BUILD_DIR = GENERATED_TEST_BUILD_DIR + "proto/";
   public static final String SMALI_DIR = TESTS_DIR + "smali/";
   public static final String SMALI_BUILD_DIR = TESTS_BUILD_DIR + "smali/";
 
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
new file mode 100644
index 0000000..485d90a
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
@@ -0,0 +1,80 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.internal.proto;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.BooleanUtils;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class Proto2ShrinkingTest extends ProtoShrinkingTestBase {
+
+  private final boolean allowAccessModification;
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{1}, allow access modification: {0}")
+  public static List<Object[]> data() {
+    return buildParameters(BooleanUtils.values(), getTestParameters().withAllRuntimes().build());
+  }
+
+  public Proto2ShrinkingTest(boolean allowAccessModification, TestParameters parameters) {
+    this.allowAccessModification = allowAccessModification;
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramFiles(PROTO2_EXAMPLES_JAR, PROTO2_PROTO_JAR, PROTOBUF_LITE_JAR)
+        .addKeepMainRule("proto2.TestClass")
+        .addKeepRules(
+            // TODO(b/112437944): Fix -identifiernamestring support.
+            "-keepnames class * extends com.google.protobuf.GeneratedMessageLite",
+            // TODO(b/112437944): Use dex item based const strings for proto schema definitions.
+            "-keepclassmembernames class * extends com.google.protobuf.GeneratedMessageLite {",
+            "  <fields>;",
+            "}",
+            // TODO(b/112437944): Do not remove proto fields that are actually used in tree shaking.
+            "-keepclassmembers,allowobfuscation class * extends",
+            "    com.google.protobuf.GeneratedMessageLite {",
+            "  <fields>;",
+            "}",
+            allowAccessModification ? "-allowaccessmodification" : "")
+        .addKeepRuleFiles(PROTOBUF_LITE_PROGUARD_RULES)
+        .setMinApi(parameters.getRuntime())
+        .compile()
+        .run(parameters.getRuntime(), "proto2.TestClass")
+        .assertSuccessWithOutputLines(
+            "--- roundtrip ---",
+            "true",
+            "123",
+            "asdf",
+            "9223372036854775807",
+            "qwerty",
+            "--- partiallyUsed_proto2 ---",
+            "true",
+            "42",
+            "--- usedViaHazzer ---",
+            "true",
+            "--- usedViaOneofCase ---",
+            "true",
+            "--- usesOnlyRepeatedFields ---",
+            "1",
+            "--- containsFlaggedOffField ---",
+            "0",
+            "--- hasFlaggedOffExtension ---",
+            "4",
+            "--- useOneExtension ---",
+            "42",
+            "--- keepMapAndRequiredFields ---",
+            "true",
+            "10",
+            "10",
+            "10");
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
new file mode 100644
index 0000000..e536067
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
@@ -0,0 +1,52 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.internal.proto;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.BooleanUtils;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class Proto3ShrinkingTest extends ProtoShrinkingTestBase {
+
+  private final boolean allowAccessModification;
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{1}, allow access modification: {0}")
+  public static List<Object[]> data() {
+    return buildParameters(BooleanUtils.values(), getTestParameters().withAllRuntimes().build());
+  }
+
+  public Proto3ShrinkingTest(boolean allowAccessModification, TestParameters parameters) {
+    this.allowAccessModification = allowAccessModification;
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramFiles(PROTO3_EXAMPLES_JAR, PROTO3_PROTO_JAR, PROTOBUF_LITE_JAR)
+        .addKeepMainRule("proto3.TestClass")
+        .addKeepRules(
+            // TODO(b/112437944): Use dex item based const strings for proto schema definitions.
+            "-keepclassmembernames class * extends com.google.protobuf.GeneratedMessageLite {",
+            "  <fields>;",
+            "}",
+            // TODO(b/112437944): Do not remove proto fields that are actually used in tree shaking.
+            "-keepclassmembers,allowobfuscation class * extends",
+            "    com.google.protobuf.GeneratedMessageLite {",
+            "  <fields>;",
+            "}",
+            allowAccessModification ? "-allowaccessmodification" : "")
+        .addKeepRuleFiles(PROTOBUF_LITE_PROGUARD_RULES)
+        .setMinApi(parameters.getRuntime())
+        .compile()
+        .run(parameters.getRuntime(), "proto3.TestClass")
+        .assertSuccessWithOutputLines("--- partiallyUsed_proto3 ---", "42");
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/internal/proto/ProtoShrinkingTestBase.java b/src/test/java/com/android/tools/r8/internal/proto/ProtoShrinkingTestBase.java
new file mode 100644
index 0000000..43ceaff
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/internal/proto/ProtoShrinkingTestBase.java
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.internal.proto;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public abstract class ProtoShrinkingTestBase extends TestBase {
+
+  public static final Path PROTOBUF_LITE_JAR =
+      Paths.get("third_party/protobuf-lite/libprotobuf_lite.jar");
+
+  public static final Path PROTOBUF_LITE_PROGUARD_RULES =
+      Paths.get("third_party/protobuf-lite/lite_proguard.pgcfg");
+
+  // Test classes for proto2.
+  public static final Path PROTO2_EXAMPLES_JAR =
+      Paths.get(ToolHelper.EXAMPLES_PROTO_BUILD_DIR).resolve("proto2.jar");
+
+  // Proto definitions used by test classes for proto2.
+  public static final Path PROTO2_PROTO_JAR =
+      Paths.get(ToolHelper.GENERATED_PROTO_BUILD_DIR).resolve("proto2.jar");
+
+  // Test classes for proto3.
+  public static final Path PROTO3_EXAMPLES_JAR =
+      Paths.get(ToolHelper.EXAMPLES_PROTO_BUILD_DIR).resolve("proto3.jar");
+
+  // Proto definitions used by test classes for proto3.
+  public static final Path PROTO3_PROTO_JAR =
+      Paths.get(ToolHelper.GENERATED_PROTO_BUILD_DIR).resolve("proto3.jar");
+}
diff --git a/third_party/proto.tar.gz.sha1 b/third_party/proto.tar.gz.sha1
new file mode 100644
index 0000000..dae5c12
--- /dev/null
+++ b/third_party/proto.tar.gz.sha1
@@ -0,0 +1 @@
+18151ef2484c03b5d1f8fc0084202cb9482f664d
\ No newline at end of file
diff --git a/third_party/protobuf-lite.tar.gz.sha1 b/third_party/protobuf-lite.tar.gz.sha1
new file mode 100644
index 0000000..6c757bb
--- /dev/null
+++ b/third_party/protobuf-lite.tar.gz.sha1
@@ -0,0 +1 @@
+f5f3295899f7eecd937830fc8a0a35a4ef5b4083
\ No newline at end of file