code: public static <T extends Message> Marshaller<T> jsonMarshaller(
        final T defaultInstance, final Parser parser, final Printer printer) {
  
      final Charset charset = Charset.forName("UTF-8");
  
      return new Marshaller<T>() {
        @Override
        public InputStream stream(T value) {
          try {
            return new ByteArrayInputStream(printer.print(value).getBytes(charset));
          } catch (InvalidProtocolBufferException e) {
            throw Status.INTERNAL
                .withCause(e)
                .withDescription("Unable to print json proto")
                .asRuntimeException();
          }
        }
  
        @SuppressWarnings("unchecked")
        @Override
        public T parse(InputStream stream) {
          Builder builder = defaultInstance.newBuilderForType();
          Reader reader = new InputStreamReader(stream, charset);
          T proto;
          try {
            parser.merge(reader, builder);
            proto = (T) builder.build();
            reader.close();
          } catch (InvalidProtocolBufferException e) {
            throw Status.INTERNAL.withDescription("Invalid protobuf byte sequence")
                .withCause(e).asRuntimeException();
          } catch (IOException e) {
            // Same for now, might be unavailable
            throw Status.INTERNAL.withDescription("Invalid protobuf byte sequence")
                .withCause(e).asRuntimeException();
          }
          return proto;
        }
      };
    }
docs: Create a {@code Marshaller} for json protos of the same type as {@code defaultInstance}.
  
  <p>This is an unstable API and has not been optimized yet for performance.