private TestRecursiveMessage makeRecursiveMessage(int depth) {
   if (depth == 0) {
     return TestRecursiveMessage.newBuilder().setI(5).build();
   } else {
     return TestRecursiveMessage.newBuilder().setA(makeRecursiveMessage(depth - 1)).build();
   }
 }
 private void assertMessageDepth(TestRecursiveMessage message, int depth) {
   if (depth == 0) {
     assertFalse(message.hasA());
     assertEquals(5, message.getI());
   } else {
     assertTrue(message.hasA());
     assertMessageDepth(message.getA(), depth - 1);
   }
 }
  public void testMaliciousRecursion() throws Exception {
    ByteString data100 = makeRecursiveMessage(100).toByteString();
    ByteString data101 = makeRecursiveMessage(101).toByteString();

    assertMessageDepth(TestRecursiveMessage.parseFrom(data100), 100);

    try {
      TestRecursiveMessage.parseFrom(data101);
      fail("Should have thrown an exception!");
    } catch (InvalidProtocolBufferException e) {
      // success.
    }

    CodedInputStream input = data100.newCodedInput();
    input.setRecursionLimit(8);
    try {
      TestRecursiveMessage.parseFrom(input);
      fail("Should have thrown an exception!");
    } catch (InvalidProtocolBufferException e) {
      // success.
    }
  }