Re: [protobuf] optional vs required

2015-06-09 Thread Colin Deasy
On Tuesday, 9 June 2015 01:27:24 UTC+1, Feng Xiao wrote:



 On Mon, Jun 8, 2015 at 7:43 AM, Colin Deasy cde...@demonware.net 
 javascript: wrote:

 Hey,

 When reading 
 https://developers.google.com/protocol-buffers/docs/proto#simple I see a 
 stark warning indicating that Required is Forever advocating the use of 
 optional with additional application level validation routines. This is 
 because if at some point a required field is no longer written, the readers 
 will break.

 However IMO, there are common cases where 'required' is a good thing - 
 given that it's enforced only during encoding/decoding.
 For example there may be some field that is 'required' (right now) to 
 both the reader and writer. Even if that changes at some point in the 
 future to become optional, the reader would likely have to be updated 
 regardless of the protocol decoding routine as it may make assumptions 
 (reasonable considering it was required in the first place) on the presence 
 of the field (e.g. the field being a key to a certain bit of data). In this 
 case the approach would be to update the .proto of all readers to make that 
 field optional, followed by updating all writers to remove the field.

 In simpler scenarios, yes, it's possible to migrate a required field to 
 optional even though it's an incompatible change, but in a more complicated 
 system, where you have many different binaries using the same proto file 
 running on thousands of machines, it's hard to tell whether all readers of 
 a proto has been updated or not. You have to be very careful with such 
 changes, and if you miss one, bad things can happen.


My point is that regardless of the size of the cluster, you will need to 
update every reader - it doesn't matter whether the 'required' constraint 
is within the protobuf deserialization logic or within the application 
logic itself.

Similar to missing an update to a certain application instance's proto 
file, you could miss an update the to application's binary itself. This is 
precisely why I don't understand the logic behind deprecating the 
'required' constraint.

 

  

 Given this, I feel that the current language of the linked document gives 
 the impression that the 'required' attribute is a Bad Thing and should be 
 avoided. I hope you can clarify if I'm missing some crucial bit of 
 information regarding it's usage.

 Thanks
 Colin

 -- 
 You received this message because you are subscribed to the Google Groups 
 Protocol Buffers group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to protobuf+u...@googlegroups.com javascript:.
 To post to this group, send email to prot...@googlegroups.com 
 javascript:.
 Visit this group at http://groups.google.com/group/protobuf.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are subscribed to the Google Groups 
Protocol Buffers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to protobuf@googlegroups.com.
Visit this group at http://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.


Re: [protobuf] Re: Issue 491 in protobuf: Optional field throws NullPointerException when not set values.

2015-06-09 Thread Josh Humphries
As a work-around, you can implement a simple protoc plugin that will
generate additional null-friendly methods into the classes already created
by the Java codegen built into protoc.

That's actually what we've done at Square. As you point out, the
null-unfriendliness is particularly burdensome with builders, for cases
where you want to use method-chaining but also conditionally set or clear a
field.

Our generated messages include getOrNull*() accessor fields (so they return
null if unset instead of the field's default value) and the builders have
setOrClear*() setter methods (that clear the field when null is passed in).




*Josh Humphries*
Manager, Shared Systems  |  Platform Engineering
Atlanta, GA  |  678-400-4867
*Square* (www.squareup.com)

On Mon, Jun 8, 2015 at 4:04 AM, Andreas V andreas.v...@gmail.com wrote:

 I know its an old thread but i use protobuf3 with Java and it has the same
 NPE behavior with .set(null-reference). Is their any chance to change this?
 an option to generating java classes would be nice. It is absolutly
 annoying to null-check on every .set method. This will lead to more errors
 in code and expand it inadequate due to chained-setters are not possible. :(

 Am Mittwoch, 29. Mai 2013 23:50:59 UTC+2 schrieb prot...@googlecode.com:


 Comment #6 on issue 491 by xiaof...@google.com: Optional field throws
 NullPointerException when not set values.
 http://code.google.com/p/protobuf/issues/detail?id=491

 We don't have the intention to change to the current behavior. Passing
 null
 is likely to be a programming error. Allowing it might do more harm than

 good.

 --
 You received this message because this project is configured to send all

 issue notifications to this address.
 You may adjust your notification preferences at:
 https://code.google.com/hosting/settings

  --
 You received this message because you are subscribed to the Google Groups
 Protocol Buffers group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to protobuf+unsubscr...@googlegroups.com.
 To post to this group, send email to protobuf@googlegroups.com.
 Visit this group at http://groups.google.com/group/protobuf.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google Groups 
Protocol Buffers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to protobuf@googlegroups.com.
Visit this group at http://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.


Re: [protobuf] protobuf 3 without threadlocal

2015-06-09 Thread 'Feng Xiao' via Protocol Buffers
On Mon, Jun 8, 2015 at 6:57 PM, Austin Schuh austin.li...@gmail.com wrote:

 Pull request sent.  I felt a lot better putting the logic in
 google/protobuf/stubs/platform_macros.h, so I put it there.

The NO_THREADLOCAL macro does not belong to platform_macros.h. It will not
work either because common.h does not include platform_macros.h so we have
to have a copy in common.h anyway.



 My platform is a very old version of Linux on an embedded box.  I'm not
 sure what to use for PLATFORM, but since I'm already re-creating the build
 commands using bazel to integrate the compiler into my project, I am now
 able to define GOOGLE_PROTOBUF_NO_THREADLOCAL myself and everything works.

 Is there any interest or plans for a set of bazel rules for the protobuf
 library?

Protobuf will be supported by bazel natively. See
https://github.com/google/bazel/issues/52



 Thanks!
 Austin

 On Mon, Jun 8, 2015 at 5:42 PM Feng Xiao xiaof...@google.com wrote:



 On Fri, Jun 5, 2015 at 7:02 PM, Austin Schuh austin.li...@gmail.com
 wrote:

 I have a target which is old enough that it doesn't support thread local
 variables.  I'd like to build the protobuf3 libraries for it.

 It looks like all I need to do is trigger arena.h and arena.cc to use
 the version of thread_cache that is used by Android which
 uses pthread_key_create.  One way to do that would be to add
 a GOOGLE_PROTOBUF_NO_THREADLOCAL variable and use that.  I've got that
 working locally as a proof of concept.  I'd like to get a change upstreamed
 to support this use case.  How would you approach solving that?  I'll
 happily write the patch if it isn't too tricky.

 I think we can change the definition in google/protobuf/stubs/common.h to
 something like:

 #if defined(ANDROID) || defined(IPHONE) ||
 defined(SOME_OTHER_PLATFORM_WITHOUT_THREADLOCAL)
 #define GOOGLE_PROTOBUF_NO_THREADLOCAL
 #endif

 #ifdef GOOGLE_PROTOBUF_NO_THREADLOCAL
 class ThreadLocalStorage {
 ...
 }
 #endif

 And also use this macro in arena.h/arena.cc as well.




 Thanks!

   Austin

  --
 You received this message because you are subscribed to the Google
 Groups Protocol Buffers group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to protobuf+unsubscr...@googlegroups.com.
 To post to this group, send email to protobuf@googlegroups.com.
 Visit this group at http://groups.google.com/group/protobuf.
 For more options, visit https://groups.google.com/d/optout.



-- 
You received this message because you are subscribed to the Google Groups 
Protocol Buffers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to protobuf@googlegroups.com.
Visit this group at http://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.


Re: [protobuf] Dynamic/run-time decoding

2015-06-09 Thread 'Feng Xiao' via Protocol Buffers
On Mon, Jun 8, 2015 at 10:23 PM, Jan Kyjovský jan.kyjov...@tieto.com
wrote:

 I have remade code so I now add into descriptor database all protofiles
 specified by directory. There is but little problem with error handling.
 From nature how I am handling errors it seems that message is possible to
 decode but there is one error in error collector which is bothering me:

 1:1: ERROR: Multiple package definitions.

 *My protos are defined as follows:*
 *addressbook_fragmented.proto:*
 import phone.proto;

 package tutorial;

 option java_package = com.example.tutorial;
 option java_outer_classname = AddressBookProtos;

 message Person {
   required string name = 1;
   required int32 id = 2;// Unique ID number for this person.
   optional string email = 3;

 //  enum PhoneType {
 //MOBILE = 0;
 //HOME = 1;
 //WORK = 2;
 //  }

   message PhoneNumber {
 required string number = 1;
 optional PhoneType type = 2 [default = HOME];
   }

   repeated PhoneNumber phone = 4;
   optional int32 age = 5;
 }

 // Our address book file is just one of these.
 message AddressBook {
   repeated Person person = 1;
 }

 *phone.proto:*
 package tutorial;

 enum PhoneType {
   MOBILE = 0;
   HOME = 1;
   WORK = 2;
 }

 Even though there is error in error collector I can ignore it and decode
 message successfully. Yet if I try to remove this package info from
 phone.proto itis not detecting any error but FindMessageTypeByName fails to
 find data type. I am suspecting since not all references for person data
 type I am asking for are resolved it fails.

 So I am confused how exactly should be these package keywords be used?

I don't see a problem in your use of package. You could try to run protoc
on these proto files and see if it reports any error. I suspect it's not
the .proto file's problem.



 On Wednesday, 3 June 2015 19:05:59 UTC+2, Feng Xiao wrote:



 On Wed, Jun 3, 2015 at 12:40 AM, Jan Kyjovský jan.ky...@tieto.com
 wrote:

 HI,

 I somehow understand what you mean but still I lack in experience with
 it. I tried to switch to descriptor database but still I got some problems.

 C_ProtoDecoder::C_ProtoDecoder(std::string strFile)
 {
 m_strProtoFile = strFile;

 // Build the descriptor pool
 m_bConstructed = ParseProtoFile(m_ProtoFileDescr);

 if (m_bConstructed)
 {
 m_ProtoDescrDatabase.Add(m_ProtoFileDescr);
 m_Pool = new DescriptorPool(m_ProtoDescrDatabase);
 }
 }

 C_ProtoDecoder::~C_ProtoDecoder()
 {
 delete m_Pool;
 }

 bool C_ProtoDecoder::DecodeDataAsTypeFromWireFormat(std::string
 strWireFormat, std::string strType)
 {
 Descriptor *descriptor = (Descriptor
 *)m_Pool-FindMessageTypeByName(strType);
 Message *message = m_MessageFactory.GetPrototype(descriptor)-New();

 if (descriptor == NULL)
 {
 char szError[256];

 sprintf(szError, Unknown data type %s!, strType.c_str());
 m_InternalPrinter.AddErrorMessage(szError);

 return false;
 }

 bool bFlag = message-ParseFromString(strWireFormat);

 if (!bFlag)
 {
 m_InternalPrinter.AddErrorMessage(Encoding error!);
 }
 else
 {
 m_Transformator.MorphToStructs(*message);
 }

 return true;
 }

 bool C_ProtoDecoder::ParseProtoFile(FileDescriptorProto *result)
 {
   int file_descriptor = open(m_strProtoFile.c_str(), O_RDONLY);

 if (file_descriptor == -1)
 {
 char szError[256];

 sprintf(szError, Invalid proto file \%s\!,
 m_strProtoFile.c_str());
 m_InternalPrinter.AddErrorMessage(szError);

 return false;
 }

 C_ParserErrorCollector errCollector;

 io::FileInputStream stream(file_descriptor);
 stream.SetCloseOnDelete(true);
 io::Tokenizer tokenizer(stream, errCollector);
 result-set_name(m_strProtoFile);

 compiler::Parser parser;

 return parser.Parse(tokenizer, result);
 }

 I have used SimpleDescriptorDatabase since it looked like it has already
 implemented and its covering what I will be requiring from it (or at least
 I think it does)

 If you use SimpleDescriptorDatabase, you need to add all .proto files
 into the database explicitly. For example, if you have 2 .proto files
 foo.proto and bar.proto, where bar.proto imports foo.proto, you need to add
 both foo.proto and bar.proto to SimpleDescriptorDatabase. If you already
 have a list of all proto files, using SimpleDescriptorDatabase should be
 fine.



 Everything is fine until I try to get descriptor by
 FindMessageTypeByName from pool. It returns null. Am I committing some
 steps?

 I don't see anything obviously wrong in your code.






 On Tuesday, 2 June 2015 19:49:53 UTC+2, Feng Xiao wrote:



 On Mon, Jun 1, 2015 at 9:55 PM, Jan Kyjovský jan.ky...@tieto.com
 wrote:

 Hi again,

 As I have stated before I am done with decoding, but now I am solving
 different type of problem. As I have mentioned before imports may prove
 problematic to our implementation.

 Let me 

Re: [protobuf] optional vs required

2015-06-09 Thread 'Feng Xiao' via Protocol Buffers
On Tue, Jun 9, 2015 at 2:29 AM, Colin Deasy cde...@demonware.net wrote:

 On Tuesday, 9 June 2015 01:27:24 UTC+1, Feng Xiao wrote:



 On Mon, Jun 8, 2015 at 7:43 AM, Colin Deasy cde...@demonware.net wrote:

 Hey,

 When reading
 https://developers.google.com/protocol-buffers/docs/proto#simple I see
 a stark warning indicating that Required is Forever advocating the use of
 optional with additional application level validation routines. This is
 because if at some point a required field is no longer written, the readers
 will break.

 However IMO, there are common cases where 'required' is a good thing -
 given that it's enforced only during encoding/decoding.
 For example there may be some field that is 'required' (right now) to
 both the reader and writer. Even if that changes at some point in the
 future to become optional, the reader would likely have to be updated
 regardless of the protocol decoding routine as it may make assumptions
 (reasonable considering it was required in the first place) on the presence
 of the field (e.g. the field being a key to a certain bit of data). In this
 case the approach would be to update the .proto of all readers to make that
 field optional, followed by updating all writers to remove the field.

 In simpler scenarios, yes, it's possible to migrate a required field to
 optional even though it's an incompatible change, but in a more complicated
 system, where you have many different binaries using the same proto file
 running on thousands of machines, it's hard to tell whether all readers of
 a proto has been updated or not. You have to be very careful with such
 changes, and if you miss one, bad things can happen.


 My point is that regardless of the size of the cluster, you will need to
 update every reader - it doesn't matter whether the 'required' constraint
 is within the protobuf deserialization logic or within the application
 logic itself.

 Similar to missing an update to a certain application instance's proto
 file, you could miss an update the to application's binary itself. This is
 precisely why I don't understand the logic behind deprecating the
 'required' constraint.

If you update your proto files in a backward compatible way, you do not
need to update every reader when you change your protos. I think this is
one of the main reasons why protobuf is created in the first place. You are
assuming we have to update all readers any way for every proto change, but
in some cases that's not even possible. And whether the required
constraint is with in the protobuf deserialization logic or in the
application logic has a crucial difference: if it's in protobuf
deserialization logic, it's enforced for all applications no matter whether
the application cares about the content of this proto. For example, a log
service may receive log messages from clients. It parses the message but
only inspect a few fields of it to determine how and where the message will
be stored persistently. Clients can define their own log entries and add
these entries to the log message. The log service may very likely have a
different release schedule from its clients. If a client decides to remove
a required field, the log service will start to fail on parsing such
messages even though it does not access these required fields by itself.
Basically besides the direct producer and consumer of a proto, there may be
some other binaries that need to parse/serialize this proto. Changing a
proto in an incompatible way is risking breaking these binaries because
it's hard to figure out what binaries are parsing your protos in a complex
environment.







 Given this, I feel that the current language of the linked document
 gives the impression that the 'required' attribute is a Bad Thing and
 should be avoided. I hope you can clarify if I'm missing some crucial bit
 of information regarding it's usage.

 Thanks
 Colin

 --
 You received this message because you are subscribed to the Google
 Groups Protocol Buffers group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to protobuf+u...@googlegroups.com.
 To post to this group, send email to prot...@googlegroups.com.
 Visit this group at http://groups.google.com/group/protobuf.
 For more options, visit https://groups.google.com/d/optout.


  --
 You received this message because you are subscribed to the Google Groups
 Protocol Buffers group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to protobuf+unsubscr...@googlegroups.com.
 To post to this group, send email to protobuf@googlegroups.com.
 Visit this group at http://groups.google.com/group/protobuf.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google Groups 
Protocol Buffers group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to