Search in sources :

Example 1 with Parser

use of com.google.protobuf.Parser in project retrofit by square.

the class ProtoConverterFactory method responseBodyConverter.

@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
    if (!(type instanceof Class<?>)) {
        return null;
    }
    Class<?> c = (Class<?>) type;
    if (!MessageLite.class.isAssignableFrom(c)) {
        return null;
    }
    Parser<MessageLite> parser;
    try {
        Method method = c.getDeclaredMethod("parser");
        //noinspection unchecked
        parser = (Parser<MessageLite>) method.invoke(null);
    } catch (InvocationTargetException e) {
        throw new RuntimeException(e.getCause());
    } catch (NoSuchMethodException | IllegalAccessException ignored) {
        // If the method is missing, fall back to original static field for pre-3.0 support.
        try {
            Field field = c.getDeclaredField("PARSER");
            //noinspection unchecked
            parser = (Parser<MessageLite>) field.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new IllegalArgumentException("Found a protobuf message but " + c.getName() + " had no parser() method or PARSER field.");
        }
    }
    return new ProtoResponseBodyConverter<>(parser, registry);
}
Also used : Method(java.lang.reflect.Method) MessageLite(com.google.protobuf.MessageLite) InvocationTargetException(java.lang.reflect.InvocationTargetException) Parser(com.google.protobuf.Parser) Field(java.lang.reflect.Field)

Example 2 with Parser

use of com.google.protobuf.Parser in project grpc-java by grpc.

the class ProtoLiteUtils method marshaller.

/** Create a {@code Marshaller} for protos of the same type as {@code defaultInstance}. */
public static <T extends MessageLite> Marshaller<T> marshaller(final T defaultInstance) {
    @SuppressWarnings("unchecked") final Parser<T> parser = (Parser<T>) defaultInstance.getParserForType();
    // TODO(ejona): consider changing return type to PrototypeMarshaller (assuming ABI safe)
    return new PrototypeMarshaller<T>() {

        @SuppressWarnings("unchecked")
        @Override
        public Class<T> getMessageClass() {
            // Precisely T since protobuf doesn't let messages extend other messages.
            return (Class<T>) defaultInstance.getClass();
        }

        @Override
        public T getMessagePrototype() {
            return defaultInstance;
        }

        @Override
        public InputStream stream(T value) {
            return new ProtoInputStream(value, parser);
        }

        @Override
        public T parse(InputStream stream) {
            if (stream instanceof ProtoInputStream) {
                ProtoInputStream protoStream = (ProtoInputStream) stream;
                // to enable this optimization.
                if (protoStream.parser() == parser) {
                    try {
                        @SuppressWarnings("unchecked") T message = (T) ((ProtoInputStream) stream).message();
                        return message;
                    } catch (IllegalStateException ex) {
                    // Stream must have been read from, which is a strange state. Since the point of this
                    // optimization is to be transparent, instead of throwing an error we'll continue,
                    // even though it seems likely there's a bug.
                    }
                }
            }
            CodedInputStream cis = null;
            try {
                if (stream instanceof KnownLength) {
                    int size = stream.available();
                    if (size > 0 && size <= GrpcUtil.DEFAULT_MAX_MESSAGE_SIZE) {
                        // buf should not be used after this method has returned.
                        byte[] buf = bufs.get().get();
                        if (buf == null || buf.length < size) {
                            buf = new byte[size];
                            bufs.set(new WeakReference<byte[]>(buf));
                        }
                        int chunkSize;
                        int position = 0;
                        while ((chunkSize = stream.read(buf, position, size - position)) != -1) {
                            position += chunkSize;
                        }
                        if (size != position) {
                            throw new RuntimeException("size inaccurate: " + size + " != " + position);
                        }
                        cis = CodedInputStream.newInstance(buf, 0, size);
                    } else if (size == 0) {
                        return defaultInstance;
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            if (cis == null) {
                cis = CodedInputStream.newInstance(stream);
            }
            // Pre-create the CodedInputStream so that we can remove the size limit restriction
            // when parsing.
            cis.setSizeLimit(Integer.MAX_VALUE);
            try {
                return parseFrom(cis);
            } catch (InvalidProtocolBufferException ipbe) {
                throw Status.INTERNAL.withDescription("Invalid protobuf byte sequence").withCause(ipbe).asRuntimeException();
            }
        }

        private T parseFrom(CodedInputStream stream) throws InvalidProtocolBufferException {
            T message = parser.parseFrom(stream, globalRegistry);
            try {
                stream.checkLastTagWas(0);
                return message;
            } catch (InvalidProtocolBufferException e) {
                e.setUnfinishedMessage(message);
                throw e;
            }
        }
    };
}
Also used : CodedInputStream(com.google.protobuf.CodedInputStream) InputStream(java.io.InputStream) CodedInputStream(com.google.protobuf.CodedInputStream) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) IOException(java.io.IOException) PrototypeMarshaller(io.grpc.MethodDescriptor.PrototypeMarshaller) KnownLength(io.grpc.KnownLength) Parser(com.google.protobuf.Parser)

Aggregations

Parser (com.google.protobuf.Parser)2 CodedInputStream (com.google.protobuf.CodedInputStream)1 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1 MessageLite (com.google.protobuf.MessageLite)1 KnownLength (io.grpc.KnownLength)1 PrototypeMarshaller (io.grpc.MethodDescriptor.PrototypeMarshaller)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 Field (java.lang.reflect.Field)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1