Giter Site home page Giter Site logo

square / wire Goto Github PK

View Code? Open in Web Editor NEW
4.2K 170.0 569.0 20.92 MB

gRPC and protocol buffers for Android, Kotlin, Swift and Java.

Home Page: https://square.github.io/wire/

License: Apache License 2.0

Shell 0.01% Java 29.10% Kotlin 62.42% Ruby 0.05% Swift 8.40% JavaScript 0.01%

wire's Introduction

Wire

See the project website for documentation and APIs.

Wire is the best solution to manage your protobuf schemas!

License

Copyright 2013 Square, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

wire's People

Contributors

autonomousapps avatar cgarrett-square avatar chris-ryan-square avatar congt avatar damianw avatar dnkoutso avatar efirestone avatar egorand avatar jakewharton avatar jgulbronson avatar jhump avatar jrodbx avatar jszumski avatar jvmakine avatar lickel avatar lkerford avatar loganj avatar mattprecious avatar mc-lovin avatar mellster2012 avatar monkey-mas avatar mpeyper avatar oldergod avatar patmalt avatar rebello95 avatar renovate[bot] avatar staktrace avatar swankjesse avatar traviscj avatar zacsweers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wire's Issues

Shade the compiler

The compiler should be self-contained so as to not cause dependency resolution problems with our upstream library usage choices.

Anecdotally, we have seen this happen twice with Wire already when used in a shared classloader such as a Gradle build script.

Field shadowed by local variable

If you have a field named result it will be shadowed by a local variable in the generated hashCode() method creating invalid Java code.

  public int hashCode() {
    int result = hashCode;
    return result != 0 ? result : (hashCode = result != null ? result.hashCode() : 0);
  }

Generating a more unique local variable name like _result avoids this problem.

  @Override
  public int hashCode() {
    int __result_ = hashCode;
    return __result_ != 0 ? __result_ : (hashCode = result != null ? result.hashCode() : 0);
  }

Wire complier cannot read the proto directory and fails silently

Hello,

I have directory structure in my android project like app/arc/main/java/com/abc/rest_of_classes

My proto directory is in src/main/proto/name_of_proto_file.proto

While compiling I used following command:

java -jar libs/wire-compiler-1.5.2-jar-with-dependencies.jar --proto_path=../src/main/proto --java_out=src/main/java/com/abc/proto

The compiler fails silently, can you help me and tell me what I am doing wrong?

Expose Constructors For Direct Initialization

The default api generates a great deal of garbage. The constant newing up of builders is really bad. Sub-messages which introduce their own sub-builders makes this worse. A simple way to fix this: offer a constructor so that messages can be built using plain old java ctors and without the creation of any intermediate objects.

toByteArray() returns zero length byte array with proguard

I have next proto file with nested messages (see below) and generated classes work just fine.. until I turn on proguard for release version. With proguard message.toByteArray() - returns zero length byte array without any errors. Without proguard everything is okay.

Tested on wire versions: 1.3.3, 1.6.0

proguard.cfg

-dontwarn okio.**

-keep class com.squareup.wire.**{*;}
-keep public class * extends com.squareup.wire.**{*;}

# Keep methods with Wire annotations (e.g. @ProtoField)
-keepclassmembers class ** {
    @com.squareup.wire.ProtoField public *;
    @com.squareup.wire.ProtoEnum public *;
}

-keep public enum com.package.messages.MessageWrapper$** {
    **[] $VALUES;
    public *;
}

.proto

package com.package.messages;

option java_package = "com.package.messages";

message MessageWrapper {
    enum MessageType {
       HOST_MESSAGE = 1;
        PEER_MESSAGE = 2;
    }

    required int64 timeSent = 1;
   required MessageType type = 2;

    optional HostMessage hostMessage = 3;
    optional PeerMessage peerMessage = 4;
}

message HostMessage {
    enum HostMessageType {
        INIT_MESSAGE = 1;
        START_COMMAND_MESSAGE = 2;
    }
    required HostMessageType messageType = 1;
    optional InitMessage initMessage = 2;
    optional int32 id = 3;

    message InitMessage {
        repeated DataMessage questions = 1;
        message DataMessage {
            optional string dataField = 1;
            repeated string dataStrings = 2;
        }
    }
}

message PeerMessage {
    enum PeerMessageType {
        HOST_ID_MESSAGE = 1;
        READY_STATE_MESSAGE = 2;
        RESPONSE_MESSAGE = 3;
    }
    required PeerMessageType messageType = 1;

    optional string hostIdString = 2;
    optional ResponseMessage responseMessage = 3;

    message ResponseMessage {
        required int32 dataId = 1;
        required int32 responseId = 2;
        required int64 elapsedTime = 3;
    }

}

wire-compiler does not support single-level package names.

For example, the following .proto file:

package protobuf;

message Foo {
    optional int32 bar = 1;
}

message Foos {
    repeated Foo foos = 1;
}

Will result in the following compiler exception:

Exception in thread "main" java.lang.RuntimeException: Unknown type Foo in message Foos
at com.squareup.wire.WireCompiler.fullyQualifiedName(WireCompiler.java:1153)
at com.squareup.wire.WireCompiler.fullyQualifiedJavaName(WireCompiler.java:1162)
at com.squareup.wire.WireCompiler.getExternalTypes(WireCompiler.java:404)
at com.squareup.wire.WireCompiler.emitMessageClass(WireCompiler.java:353)
at com.squareup.wire.WireCompiler.compileOne(WireCompiler.java:195)
at com.squareup.wire.WireCompiler.compile(WireCompiler.java:175)
at com.squareup.wire.WireCompiler.main(WireCompiler.java:145)

Empty List should be different from null

When a REPEATED List field is empty but not null, wire data.toByteArray() and then wire.parseFrom() will make the list null.

Simple test case:

MyData data = new MyData.Builder().list(new ArrayList()).build();

assert(data.list != null); // pass

data = wire.parseFrom(data.toByteArray(), MyTestData.class);

assert(data.list != null); // fail

Problem parsing when using extensions

I tried to do the following with 'msg' as it is created in lines 290-300 of WireTest.java (https://github.com/square/wire/blob/master/wire-runtime/src/test/java/com/squareup/wire/WireTest.java):

byte[] wireData = msg.toByteArray();
WireInput input = WireInput.newInstance(wireData);
SimpleMessage newMsg = new Wire().parseFrom(input, SimpleMessage.class);
assertEquals(msg, newMsg);

It fails since newMsg does not match the input -- extensions is empty. Eg:

java.lang.AssertionError: expected: <SimpleMessage{optional_external_msg=ExternalMessage{{extensions={125=[444, 555], 126=333, 127=222}}}, required_int32=456}> but was:<SimpleMessage{optional_external_msg=ExternalMessage{{extensions={}}}, required_int32=456}>

However, what this code doing seems reasonable:

  1. It gets a byte[] with the message wire format,
  2. Creates a WireInput from that byte[],
  3. Parses a SimpleMessage from this WireInput.

Clearly something is askew, but I can't tell what.

And incidentally, this seems to work fine for Messages without extensions.

Have message classes implement Serializable

One feature I used quite a bit with the reference implementation of PB is that its objects automatically implement Serializable.

I'd be happy to try to dig in and implement this feature. Does the author have any philosophical objection to that?

Gradle plugin

Since this implementation of protobuf was written with Android in mind, it's fitting that we provide a first-party plugin for Gradle.

The plugin will be released to Maven central along with the other Wire artifacts as wire-gradle-plugin. The plugin ID would be com.squareup.wire. We should also look at deploying to Gradle's new plugin registry which might allow skipping the actual dependency declaration in the future.

Compiler options will be exposed through an extension object named wire. Examples of this would be generating code for options, extension registry name, etc. For example:

wire {
  generateOptions true
  extensionRegistry 'com.example.protos.Extensions'
}

Open questions:

  • Would we only target protos which were hosted in-module (e.g., src/main/proto) and not ones pulled in from external sources either on the classpath or via HTTP, etc.?

What Proguard rules are recommended?

By default, using Proguard on the Wire library will break the resulting APK due to these notes:

Note: the configuration keeps the entry point 'com.squareup.wire.Message { Message(com.squareup.wire.Message$Builder); }', but not the descriptor class 'com.squareup.wire.Message$Builder'
Note: the configuration keeps the entry point 'com.squareup.wire.Message { void write(com.squareup.wire.WireOutput); }', but not the descriptor class 'com.squareup.wire.WireOutput'
Note: the configuration keeps the entry point 'com.squareup.wire.Message { void writeUnknownFieldMap(com.squareup.wire.WireOutput); }', but not the descriptor class 'com.squareup.wire.WireOutput'
Note: the configuration keeps the entry point 'com.squareup.wire.Message { com.squareup.wire.UnknownFieldMap access$000(com.squareup.wire.Message); }', but not the descriptor class 'com.squareup.wire.Message'
Note: the configuration keeps the entry point 'com.squareup.wire.Message$Builder { Message$Builder(com.squareup.wire.Message); }', but not the descriptor class 'com.squareup.wire.Message'
Note: the configuration keeps the entry point 'com.squareup.wire.Message$Builder { void addLengthDelimited(int,com.squareup.wire.ByteString); }', but not the descriptor class 'com.squareup.wire.ByteString'

I assume the simplest fix is just to preserve all the files in the library like this (the downside is that this simple rule will miss out on potential opportunities to shrink and optimize the code):

-keep class com.squareup.wire.** { *; }

However, I'm guessing we may also need rules similar to Otto to preserve the annotations, e.g.

# Keep methods with Wire annotations (e.g. @ProtoField)
-keepclassmembers class ** {
    @com.squareup.wire.ProtoField public *;
}

I can add any Proguard rules you recommend to my pull request
(#69).

I might not be in a position to actually test a release build for a few days though.

Cheers,
Dan

Generate classes for messages-with-extensions

Given a message with extensions, generate for each extension a class which has the union of fields from the message and the extension. Ideally do this with inheritance to support polymorphism, such that the extensions generate subclasses of the message class.

Change the behavior of ByteString.of() method or make the functionality more explicit

Currently the function ByteString.of(String...) returns back a base64 encoded ByteString. This behavior is ambiguous when compared to the corresponding behavior related to the bytes parameter.

Code: https://github.com/square/wire/blob/master/wire-runtime/src/main/java/com/squareup/wire/ByteString.java#L63

Example:
ByteString.of("WIRE_COOL".getBytes()); // Produces: 'V0lSRV9DT09M'

whereas
ByteString.of("WIRE_COOL"); //produces 'WIRECOOL' in Base64 format

Perhaps the distinction can be made more explicit to avoid decoding errors after serialization?

Infer Proto Directory Root

Protos declare a package so we should be able to infer the location of the "root" of the containing directory.

Wire v2 Working Document

Since multiple people are expressing interest in pushing this along I thought it best to write down what we want v2 to be. This will ensure everyone is on the same page and allow parallel work to be done. This is meant to be a living document that will be edited as things change.

Summary:

  • Simplify use in a toolchain.
  • Leverage parsing & pruning to generate things other than Wire-specific Java code.
  • Alter the behavior of the Wire-specific generated Java code.
  • More advanced CLI
  • Other features

Simplify use in a toolchain.

The Wire compiler has no API which means you are forced to interact with by calling the main() method with CLI arguments.

For example,

task generateProtos << {
  def protoRoots = project.file("proto_roots.txt").readLines()
  def protoFiles = project.file("proto_files.txt").readLines()
  def compiler = new WireCompiler(protoDir.toString(), protoFiles, protoRoots, 'src/main/java', null, false)
  compiler.compile()
}

This is unsatisfactory. The tests for wire are also forced into doing this.

We should provide an API which lets you very easily specify all of the required data for compilation.

Random example that's not a suggestion of what the actual API should be:

new WireCompiler()
    .addDirectory(new File("/foo/bar/protos"))
    .addProtoRoot("example.thing.Foo")
    .addProtoRoot("example.thing.Bar")
    .build();

(This is done on version-two branch)

Leverage parsing & pruning to generate things other than Wire-specific Java code.

Code to serialize protocol buffers are not the only thing you want to generate. We want to generate Retrofit interfaces based on RPC definitions, for example. Additionally there's no reason that you couldn't general Python, Objective-C, or even protobuf-compliant code.

The parsing of protos is easy but pruning them requires contextual knowledge of where they are stored and dependency resolution semantics is hard. Since Wire is already doing all of this work, we should expose it for others to consume and do with what they'd like.

After parsing and pruning an immutable representation of everything required for generating code should be available. We can re-use protoparser's model objects since they are immutable and simple omit the messages, enums, and rpcs which have been pruned.

(This is done on version-two branch)

Alter the behavior of the Wire-specific generated Java code.

This is similar to the previous point, but involves hooking into the Wire-specific code generation rather than a completely separate generator.

For example, naming of fields and methods is a high-contention point that could easily be solved by a method which can be overridden to specify a different naming scheme.

protected String toJavaName(String protoName) {
  // Note: You would want to cache the converter, obviously.
  return CaseFormat.LOWER_UNDERSCORE.converterTo(CaseFormat.LOWER_CAMEL).convert(protoName);
}

This would also allow for hooks to augment generation. The JavaWriter could be handed to empty protected methods before and after certain blocks of code for additional logic to be put in place. For example, additional validation code in the constructor which takes the builder.

See Shawn's branch for a specific spike on what might be needed. Maybe we can get him to write a more fleshed out design here.

More advanced CLI

With all of the aforementioned changes, it should come as no surprise that a more powerful CLI is needed. By not attempting to mirror the protoc CLI we are unblocked to make something that's both simple, declarative, and powerful.

more to come...

Other features

  • Protos are not always on-disk and we should not require them to be. In a traditional Maven build they are often placed in src/main/protos and can be published in the artifact to Maven central or any other repository manager. We should support a way of loading them.
  • Support multiple proto directories for dependency resolution.

TODO

  • Parsing
  • Pruning
  • CLI
  • Emitting old Wire-specific Java code. Parsing and pruning already return an immutable model of the protos we just need to write a self-contained emitter.
  • Validation hooks for Wire Java code emitter.

Fields tag can have duplicated values

message Foo {
  optional int32 bar = 1;
  optional int32 quix = 1;
}

Compiles just fine.

This should only be allowed if allow_alias = true.

message Foo {
  option allow_alias = true;
  optional int32 bar = 1;
  optional int32 quix = 1;
}

Add error message for missing package in .proto file

I just spent a fair amount of time trying to figure out why I was getting a NullPointerException when compiling a .proto file. It turns out you need to have a package specified.

A simple error message would help make that very clear.

Thanks!

Switch to Okio Buffer, ByteString

There's an opportunity to streamline wire by employing and accepting okio Buffers and ByteStrings as opposed to byte arrays and wire's ByteString.

While this is api-breaking, we should be able to measure improvements in marshaling throughput as well open ourselves to compatible representations of ByteString across Square OSS libraries such as okhttp.

cc @swankjesse

Annotated constructor parameters to reference the fields

We're looking to store protos long term. There's some concern with using the protobuf binary format because the format is not self-describing and it's quite likely (after 7-10 years) the original code and schema could be lost. I'm mostly able to convert Wire protobufs to XML thanks to the very-helpful '@protofield' annotation on the fields. But when it comes time to deserialize these things it's not so easy. (Reflectively working with the builder api is pain.)

#136 added the ability to construct messages using a ctor. Would it also be possible to annotate the parameters to the ctor such that it would be possible to dynamically match fields to ctor parameters?

Eg.

a message like:

public final class TextContent extends Message {

  public static final String DEFAULT_CONTENTTYPE = "";
  public static final String DEFAULT_CONTENT = "";

  @ProtoField(tag = 1, type = STRING, label = REQUIRED)
  public final String contentType;

  @ProtoField(tag = 2, type = STRING, label = REQUIRED)
  public final String content;

  private TextContent(Builder builder) {
    super(builder);
    this.contentType = builder.contentType;
    this.content = builder.content;
  }

...
}

Could have a generated constructor of:

public TextContent(@ProtoFieldRef(tag= 1) String contentType, @ProtoFieldRef(tag = 2) String content) {
...
}

This would allow a tool to reflectively examine a Protobuf Message and serialize all its fields and then later on when it comes time to deserialize those fields, invoke a constructor and know which fields go with each constructor parameter. Make sense...?

readString error.

I have searched on this project and on the web and I cannot find an answer to this issue. I replaced the google protobuf with your wire project (using the compiled runtime jar from maven using gradle) and everything was working fine until this morning. Now Wire will not parse the inputstream and I don't know why. The error I am gettting is:

java.lang.NoSuchMethodError: No interface method readString(JLjava/nio/charset/Charset;)Ljava/lang/String; in class Lokio/BufferedSource; or its super classes (declaration of 'okio.BufferedSource' appears in /system/framework/okhttp.jar)
at com.squareup.wire.WireInput.readString(WireInput.java:124)
at com.squareup.wire.MessageAdapter.readValue(MessageAdapter.java:626)
at com.squareup.wire.MessageAdapter.read(MessageAdapter.java:588)
at com.squareup.wire.MessageAdapter.readMessage(MessageAdapter.java:645)
at com.squareup.wire.MessageAdapter.readValue(MessageAdapter.java:628)
at com.squareup.wire.MessageAdapter.read(MessageAdapter.java:588)
at com.squareup.wire.Wire.parseFrom(Wire.java:167)
at com.squareup.wire.Wire.parseFrom(Wire.java:148)
at com.myapp.service.providers.ManifestProvider$QueueRunner.run(ManifestProvider.java:67)
at java.lang.Thread.run(Thread.java:818)

It is probably something I am doing wrong, but I have no idea where to begin on this.

Standardize generated field names based on convention

// Copied from JavaWriter
Currently, the field names are directly derived from the .proto files. However, it would be better if while generating the code some conventions can be followed like:

  • Hungarian notation for fields
  • Convert underscore in proto field names to camel case

Right now, a field declared as request_id remains as request_id in Java Code and sometimes feels weird to be calling a function like request_id(21)

will follow up with a pull request.

NullPointerException

Version : latest version

code:
Wire wire = new Wire() ;
PB_FavoritesRsp response = wire.parseFrom(bytes, PB_FavoritesRsp.class) ;

error:

03-21 12:53:08.024: E/ANDROID_LAB(8998): [tid=18630] Error[java.lang.NullPointerException
03-21 12:53:08.024: E/ANDROID_LAB(8998): at com.squareup.wire.WireInput.refillBuffer(WireInput.java:350)
03-21 12:53:08.024: E/ANDROID_LAB(8998): at com.squareup.wire.WireInput.isAtEnd(WireInput.java:404)
03-21 12:53:08.024: E/ANDROID_LAB(8998): at com.squareup.wire.WireInput.readTag(WireInput.java:86)
03-21 12:53:08.024: E/ANDROID_LAB(8998): at com.squareup.wire.MessageAdapter.read(MessageAdapter.java:519)
03-21 12:53:08.024: E/ANDROID_LAB(8998): at com.squareup.wire.Wire.parseFrom(Wire.java:144)
03-21 12:53:08.024: E/ANDROID_LAB(8998): at com.squareup.wire.Wire.parseFrom(Wire.java:135)

Is bytes is null?

Fields tag can have value 0

message Foo {
  optional int32 bar = 0;
}

Tag 0 shouldn't be allowed. It currently compile fines with Wire.

enums can have same name in same namespace

message Foo {
  enum Bar {
    QUIX = 0;
  }

  enum Bar2 {
    QUIX = 0;
  }
}

Compiles just fine.

protoc fails:

"QUIX" is already defined in "Foo".
Note that enum values use C++ scoping rules, meaning that enum values are siblings of their type, not children of it. Therefore, "QUIX" must be unique within "Foo", not just within "Bar".

How to merge data from a Builder instance to another?

Hi, guys
I have a question on the usage of Wire:
How can i clear all data from a Builder instance and merge data from another instance? as i known in official protobuf, use clear() and mergeFrom() to achieve this. Are there any similiar api in Wire?

Thanks.

Feature request: wire-compile: generate Java annotations from "options" in ".proto" file

Hi.

I am using Swagger's @apimodel and @ApiModelProperty annotations in my DTOs to automatically document my API request and response classes in Swagger. Swagger easily takes these annotations and generates live documentation where you can even invoke the API methods. (See example here: http://petstore.swagger.wordnik.com/)

I thought it would be very useful to generate my whole DTO tree of classes from a single ".proto" file instead of manually writing boiler plate Java classes. It's even more elegant than writing classes with Lombok @builder annotation, which is what I am doing today.

I thought that the equivalent to Java annotations in Protobuf is options.
Maybe it would be possible to add "com.wordnik.swagger.annotations.ApiModel" option to a Protobuf message and "com.wordnik.swagger.annotations.ApiModelProperty" option to a Protobuf field, and wire-compiler will take them and generate the appropriate Java annotations for the class and the field.

Enabling such a feature in wire-compile will leverage it to a whole new world of data-types and data-transfer-objects generation from Protobuf with the ability to annotate the classed with various frameworks stuff like Jackson, Java JPA, Spring and more.

What do you think?
David.

There is no support for the -I include similar to protoc

If you have .proto files which expect a pre-defined include path similar to C/C++ compiler option -I it will not compile with the wire compiler because the imports won't be found.

Suggestion: Add a --includes that accepts a file containing a list of directories to search similar to the protos.include. Then search the list in the findDep if it's not found based on local or absolute path.

Add Message.writeTo(Sink)

Some libraries (like Tape) provide access to an outputstream but which may actually be a ByteArrayOutputStream (like Tape). It'd be nice to avoid an extra byte array if we can swing it.

Provide JARs with releases to avoid people needing to build the source

It's a bit of a pain for developers to need to build the Wire JARs. Please can they be included in the Github releases? If they are already somewhere then it would be great to update the README to spell that out (sorry if I missed it).

The average developer probably just wants to drop the JARs somewhere to try them.

Cheers,
Dan

P.S. Thanks a lot for this library, it looks awesome!

Provide ProtobufHttpMessageConverter for Spring MVC

Hi.

I really liked your "wire" open source project.

I just saw this mini project: https://github.com/making/spring-mvc-tutorial-protobuf
It's about easily integrating Protobuf in Spring MVC.

However, the amazing results are only achieved using Google's own protobuf java library, not using your amazing Wire framework.
It's all about Spring's ProtobufHttpMessageConverter class which is not compatible with Wire.

I wonder if you can mimic this behavior also on Wire?

I may provide pull request if I have some time but either way I thought it's good to notice you about this nice and easy feature.

Thanks,
David.

How to handle default values?

Hi,

I've just started working with wire in my project and I find it very cool. Thanks for your awesome work.

The only thing I'm finding not handy at all is how default values are handled. For exemple I have a class Configuration representing the url, routes I want to use for the communication. When my app launches, I'm using a default Configuration which was described in a proto file and then I'm checking one from the network. The network doesn't return everything, just specific values (the rest have the default values). Two issues with that:

  • How do I create a default instance? The only way I found was to use the DEFAULT_ static attributes for each attribute (very messy)
  • How do I make the instance set its attributes values to the default value if they are not specified?

I've noticed the method Wire.get(val, defVal) but I don't see the point of using that for every attributes.

I don't understand why the Builder doesn't set its values to the default ones in its constructor.

Feature pitch: MessageMethods

I've got a proto message called Money. It's straightforward:

message Money {
  optional int64 amount = 2;
  optional CurrencyCode currency_code = 3 [default = USD];
}

But the class it generates isn't ergonomic. I want my Wire classes to be easy and awesome like the classes I write myself. In particular, I want to do stuff like this:

    Money price = Money.usd(500_00);
    Money taxes = Money.usd(10_00);
    Money total = price.plus(taxes);

I propose we embrace our dear friend annotation processing in Wire. Specifically I'd like to be able to write a utility class composed of static methods:

@MessageMethods(Money.class)
final class MoneyMethods {
  public static Money plus(Money me, Money other) {
    checkArgument(me.currency_code == other.currency_code);
    return new Money.Builder(me)
        .amount(me.amount + other.amount)
        .build();
  }

  public static Money usd(long amount) {
    return new Money.Builder()
        .currency_code(CurrencyCode.USD)
        .amount(amount)
        .build();
  }
}

This would cause Wire to include delegating methods in its generated Message:

public final class Money extends Message {
  ...

  public Money plus(Money other) {
    return MoneyMethods.plus(this, other);
  }

  public static Money usd(long amount) {
    return MoneyMethods.usd(amount);
  }

The rules would be straightforward. If a MoneyMethods method's first argument is Money, we generate an instance method that delegates and passes this as that first argument. Otherwise we generate a static method that delegates.

MoneyMethods need not be public, but only its public methods yield generated trampolines.

Decouple Parsing and Processing from Language Emitting

This would help make the library extension friendly. You could easily write an "ObjectiveWire" variant (in Java, mind you) that depended on this library's parsing and processing but chose to emit Objective-C code. There's no reason everyone should have to figure out parsing and dependency analysis just to emit different languages.

  • Parsing
  • Pruning
  • Emitting
  • Command-line interface

Support An "And Dependencies" Flag

Where the list of protos is what I want but I also want its transitive message dependencies only (NOT the transitive file dependencies).

For example, if A.proto has a message A that depends on B2 from B.proto, make sure that the fictional B1 and B3 types that exist inside B.proto aren't generated.

Missing package name

Hi!

All generated Java classes are without package name. What am I doing wrong?

Here is my compilation code:

java -jar wire-compiler-1.6.0-jar-with-dependencies.jar \
    --java_out=../app/src/main/java/my/package/name/proto api.proto

First few lines look like this:

// Code generated by Wire protocol buffer compiler, do not edit.
// Source file: /full/path/to/api.proto
import com.squareup.wire.Message;
import com.squareup.wire.ProtoField;

import static com.squareup.wire.Message.Datatype.INT32;
import static com.squareup.wire.Message.Datatype.STRING;
import static com.squareup.wire.Message.Label.REQUIRED;

public final class ResponseError extends Message {

Enum value option referencing a repeated field uses unimported 'asList' method

The code:

import "google/protobuf/descriptor.proto";

extend google.protobuf.EnumValueOptions {
 optional Values values = 50000;
}

message Values {
 repeated int32 v = 1;
}

enum MyEnum {
 FOO = 1 [(values) = { v: [1, 2, 3] } ];
}

generates an initializer for FOO with a call to asList that does not resolve to Message.asList.
Ideally we would detect this case and emit a static import of java.util.Arrays.asList as needed. This is probably best done in Wire v2 since we will be performing more option parsing up front.

Generate proto file from POJO

Hi,

It would be nice to generate proto file from Java class!

So using Wire would be as simple as Json with GSon.

Regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.