static void verifyDeterministic(ProtoCoder<?> coder) throws NonDeterministicException {
    Class<? extends Message> message = coder.getMessageType();
    ExtensionRegistry registry = coder.getExtensionRegistry();
    Set<Descriptor> descriptors = getRecursiveDescriptorsForClass(message, registry);
    for (Descriptor d : descriptors) {
      for (FieldDescriptor fd : d.getFields()) {
        // If there is a transitively reachable Protocol Buffers map field, then this object cannot
        // be encoded deterministically.
        if (fd.isMapField()) {
          String reason =
              String.format(
                  "Protocol Buffers message %s transitively includes Map field %s (from file %s)."
                      + " Maps cannot be deterministically encoded.",
                  message.getName(), fd.getFullName(), fd.getFile().getFullName());
          throw new NonDeterministicException(coder, reason);
        }
      }
    }
  }
@Test
  public void testMessageWithTransitiveMapIsNotDeterministic() throws NonDeterministicException {
    String mapFieldName = MessageWithMap.getDescriptor().findFieldByNumber(1).getFullName();
    thrown.expect(NonDeterministicException.class);
    thrown.expectMessage(ReferencesMessageWithMap.class.getName());
    thrown.expectMessage("transitively includes Map field " + mapFieldName);
    thrown.expectMessage("file " + MessageWithMap.getDescriptor().getFile().getName());

    verifyDeterministic(ProtoCoder.of(ReferencesMessageWithMap.class));
  }