#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
#include <map>
#include <string>
#include <google/protobuf/compiler/java/java_field.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace java {
class MessageFieldGenerator : public FieldGenerator {
 public:
  explicit MessageFieldGenerator(const FieldDescriptor* descriptor,
      int messageBitIndex, int builderBitIndex);
  ~MessageFieldGenerator();
  
  int GetNumBitsForMessage() const;
  int GetNumBitsForBuilder() const;
  void GenerateInterfaceMembers(io::Printer* printer) const;
  void GenerateMembers(io::Printer* printer) const;
  void GenerateBuilderMembers(io::Printer* printer) const;
  void GenerateInitializationCode(io::Printer* printer) const;
  void GenerateBuilderClearCode(io::Printer* printer) const;
  void GenerateMergingCode(io::Printer* printer) const;
  void GenerateBuildingCode(io::Printer* printer) const;
  void GenerateParsingCode(io::Printer* printer) const;
  void GenerateParsingDoneCode(io::Printer* printer) const;
  void GenerateSerializationCode(io::Printer* printer) const;
  void GenerateSerializedSizeCode(io::Printer* printer) const;
  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
  void GenerateEqualsCode(io::Printer* printer) const;
  void GenerateHashCode(io::Printer* printer) const;
  string GetBoxedType() const;
 private:
  const FieldDescriptor* descriptor_;
  map<string, string> variables_;
  const int messageBitIndex_;
  const int builderBitIndex_;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
  void PrintNestedBuilderCondition(io::Printer* printer,
      const char* regular_case, const char* nested_builder_case) const;
  void PrintNestedBuilderFunction(io::Printer* printer,
      const char* method_prototype, const char* regular_case,
      const char* nested_builder_case,
      const char* trailing_code) const;
};
class RepeatedMessageFieldGenerator : public FieldGenerator {
 public:
  explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
      int messageBitIndex, int builderBitIndex);
  ~RepeatedMessageFieldGenerator();
  
  int GetNumBitsForMessage() const;
  int GetNumBitsForBuilder() const;
  void GenerateInterfaceMembers(io::Printer* printer) const;
  void GenerateMembers(io::Printer* printer) const;
  void GenerateBuilderMembers(io::Printer* printer) const;
  void GenerateInitializationCode(io::Printer* printer) const;
  void GenerateBuilderClearCode(io::Printer* printer) const;
  void GenerateMergingCode(io::Printer* printer) const;
  void GenerateBuildingCode(io::Printer* printer) const;
  void GenerateParsingCode(io::Printer* printer) const;
  void GenerateParsingDoneCode(io::Printer* printer) const;
  void GenerateSerializationCode(io::Printer* printer) const;
  void GenerateSerializedSizeCode(io::Printer* printer) const;
  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
  void GenerateEqualsCode(io::Printer* printer) const;
  void GenerateHashCode(io::Printer* printer) const;
  string GetBoxedType() const;
 private:
  const FieldDescriptor* descriptor_;
  map<string, string> variables_;
  const int messageBitIndex_;
  const int builderBitIndex_;
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
  void PrintNestedBuilderCondition(io::Printer* printer,
      const char* regular_case, const char* nested_builder_case) const;
  void PrintNestedBuilderFunction(io::Printer* printer,
      const char* method_prototype, const char* regular_case,
      const char* nested_builder_case,
      const char* trailing_code) const;
};
}  
}  
}  
}  
#endif