private FieldDeclaration createDeleteFlagValueField(
     EmitContext context, ModelDeclaration model, AstLiteral deleteFlagValue) {
   assert context != null;
   assert model != null;
   assert deleteFlagValue != null;
   ModelFactory f = context.getModelFactory();
   Type type;
   Expression value;
   switch (deleteFlagValue.kind) {
     case BOOLEAN:
       type = context.resolve(boolean.class);
       value = Models.toLiteral(f, deleteFlagValue.toBooleanValue());
       break;
     case INTEGER:
       type = context.resolve(int.class);
       value = Models.toLiteral(f, deleteFlagValue.toIntegerValue().intValue());
       break;
     case STRING:
       type = context.resolve(Text.class);
       value =
           new TypeBuilder(f, context.resolve(Text.class))
               .newObject(Models.toLiteral(f, deleteFlagValue.toStringValue()))
               .toExpression();
       break;
     default:
       throw new AssertionError(deleteFlagValue);
   }
   return f.newFieldDeclaration(
       null,
       new AttributeBuilder(f).Private().Static().Final().toAttributes(),
       type,
       f.newSimpleName(FIELD_DELETE_FLAG_VALUE),
       value);
 }
 @Override
 public List<Annotation> getTypeAnnotations(EmitContext context, ModelDeclaration model)
     throws IOException {
   Type type = generate(context, model);
   ModelFactory f = context.getModelFactory();
   return new AttributeBuilder(f)
       .annotation(
           context.resolve(ModelInputLocation.class), f.newClassLiteral(context.resolve(type)))
       .toAnnotations();
 }
 private MethodDeclaration createGetModelType() {
   return createGetter(
       new TypeBuilder(f, context.resolve(Class.class))
           .parameterize(
               f.newWildcard(
                   WildcardBoundKind.UPPER_BOUNDED, context.resolve(model.getSymbol())))
           .toType(),
       "getModelType",
       f.newClassLiteral(context.resolve(model.getSymbol())));
 }
 private Type generate(EmitContext context, ModelDeclaration model) throws IOException {
   EmitContext next =
       new EmitContext(
           context.getSemantics(),
           context.getConfiguration(),
           model,
           NameConstants.CATEGORY_IO,
           "{0}Input");
   Generator.emit(next, model);
   return context.resolve(next.getQualifiedTypeName());
 }
 private DescriptionGenerator(
     EmitContext context, ModelDeclaration model, Name supportClassName, boolean importer) {
   assert context != null;
   assert model != null;
   assert supportClassName != null;
   this.context = context;
   this.model = model;
   this.f = context.getModelFactory();
   this.importer = importer;
   this.supportClass = context.resolve(supportClassName);
 }
 private TypeBodyDeclaration createCloser() {
   return f.newMethodDeclaration(
       null,
       new AttributeBuilder(f)
           .annotation(context.resolve(Override.class))
           .Public()
           .toAttributes(),
       Collections.<TypeParameterDeclaration>emptyList(),
       context.resolve(void.class),
       f.newSimpleName("close"),
       Collections.<FormalParameterDeclaration>emptyList(),
       0,
       Collections.singletonList(context.resolve(IOException.class)),
       f.newBlock(createCloserBody()));
 }
 @Override
 public List<Type> getInterfaces(EmitContext context, ModelDeclaration model) throws IOException {
   if (isTarget(model) == false) {
     return Collections.emptyList();
   }
   return Arrays.asList(context.resolve(ThunderGateCacheSupport.class));
 }
 private Generator(EmitContext context, ModelDeclaration model) {
   assert context != null;
   assert model != null;
   this.context = context;
   this.model = model;
   this.f = context.getModelFactory();
 }
 private TypeBodyDeclaration createConstructor() {
   return f.newConstructorDeclaration(
       new JavadocBuilder(f)
           .text("インスタンスを生成する。")
           .param(createParserFieldName())
           .text("利用するパーサー")
           .exception(context.resolve(IllegalArgumentException.class))
           .text("引数に<code>null</code>が指定された場合")
           .toJavadoc(),
       new AttributeBuilder(f).Public().toAttributes(),
       context.getTypeName(),
       Collections.singletonList(
           f.newFormalParameterDeclaration(
               context.resolve(RecordParser.class), createParserFieldName())),
       createConstructorBody());
 }
 private void emit() throws IOException {
   ClassDeclaration decl =
       f.newClassDeclaration(
           new JavadocBuilder(f)
               .text("An abstract implementation of ")
               .linkType(context.resolve(model.getSymbol()))
               .text(" {0} description using WindGate CSV", importer ? "importer" : "exporter")
               .text(".")
               .toJavadoc(),
           new AttributeBuilder(f).Public().Abstract().toAttributes(),
           context.getTypeName(),
           context.resolve(Models.toName(f, importer ? IMPORTER_TYPE_NAME : EXPORTER_TYPE_NAME)),
           Collections.<com.asakusafw.utils.java.model.syntax.Type>emptyList(),
           createMembers());
   context.emit(decl);
 }
 private void emit() throws IOException {
   ClassDeclaration decl =
       f.newClassDeclaration(
           new JavadocBuilder(f)
               .text("TSVファイルなどのレコードを表すファイルを入力として<code>{0}</code>を読み出す", model.getName())
               .toJavadoc(),
           new AttributeBuilder(f).Public().Final().toAttributes(),
           context.getTypeName(),
           Collections.<TypeParameterDeclaration>emptyList(),
           null,
           Collections.singletonList(
               f.newParameterizedType(
                   context.resolve(ModelInput.class), context.resolve(model.getSymbol()))),
           createMembers());
   context.emit(decl);
 }
 private TypeBodyDeclaration createParserField() {
   return f.newFieldDeclaration(
       null,
       new AttributeBuilder(f).Private().Final().toAttributes(),
       context.resolve(RecordParser.class),
       createParserFieldName(),
       null);
 }
 private FieldDeclaration createPrivateField(Class<?> type, SimpleName name) {
   return f.newFieldDeclaration(
       null,
       new AttributeBuilder(f).Private().Final().toAttributes(),
       context.resolve(type),
       name,
       null);
 }
 private MethodDeclaration createReader() {
   return f.newMethodDeclaration(
       null,
       new AttributeBuilder(f)
           .annotation(context.resolve(Override.class))
           .Public()
           .toAttributes(),
       Collections.<TypeParameterDeclaration>emptyList(),
       context.resolve(boolean.class),
       f.newSimpleName("readTo"),
       Collections.singletonList(
           f.newFormalParameterDeclaration(
               context.resolve(model.getSymbol()), createModelParameterName())),
       0,
       Collections.singletonList(context.resolve(IOException.class)),
       f.newBlock(createReaderBody()));
 }
 private MethodDeclaration createTimestampColumnMethod(
     EmitContext context, ModelDeclaration model, PropertySymbol timestamp) {
   assert context != null;
   assert model != null;
   assert timestamp != null;
   ModelFactory f = context.getModelFactory();
   String name = OriginalNameEmitter.getOriginalName(timestamp.findDeclaration());
   List<Statement> statements = Lists.create();
   statements.add(new ExpressionBuilder(f, Models.toLiteral(f, name)).toReturnStatement());
   return f.newMethodDeclaration(
       null,
       new AttributeBuilder(f).annotation(context.resolve(Override.class)).Public().toAttributes(),
       context.resolve(String.class),
       f.newSimpleName("__tgc__TimestampColumn"),
       Collections.<FormalParameterDeclaration>emptyList(),
       statements);
 }
 private MethodDeclaration createModelVersionMethod(
     EmitContext context, ModelDeclaration model, CacheSupportTrait trait) {
   assert context != null;
   assert model != null;
   assert trait != null;
   ModelFactory f = context.getModelFactory();
   List<Statement> statements = Lists.create();
   statements.add(
       new ExpressionBuilder(f, Models.toLiteral(f, computeModelVersion(context, model, trait)))
           .toReturnStatement());
   return f.newMethodDeclaration(
       null,
       new AttributeBuilder(f).annotation(context.resolve(Override.class)).Public().toAttributes(),
       context.resolve(long.class),
       f.newSimpleName("__tgc__DataModelVersion"),
       Collections.<FormalParameterDeclaration>emptyList(),
       statements);
 }
 private MethodDeclaration createGetConfiguration() {
   List<Statement> statements = Lists.create();
   List<Expression> arguments = Lists.create();
   arguments.add(
       new TypeBuilder(f, context.resolve(Charset.class))
           .method("forName", Models.toLiteral(f, conf.getCharsetName()))
           .toExpression());
   if (conf.isEnableHeader()) {
     SimpleName headers = f.newSimpleName("headers");
     statements.add(
         new TypeBuilder(f, context.resolve(ArrayList.class))
             .parameterize(context.resolve(String.class))
             .newObject()
             .toLocalVariableDeclaration(
                 new TypeBuilder(f, context.resolve(List.class))
                     .parameterize(context.resolve(String.class))
                     .toType(),
                 headers));
     for (PropertyDeclaration property : model.getDeclaredProperties()) {
       if (isValueField(property)) {
         String fieldName = CsvFieldTrait.getFieldName(property);
         statements.add(
             new ExpressionBuilder(f, headers)
                 .method("add", Models.toLiteral(f, fieldName))
                 .toStatement());
       }
     }
     arguments.add(headers);
   } else {
     arguments.add(
         new TypeBuilder(f, context.resolve(CsvConfiguration.class))
             .field("DEFAULT_HEADER_CELLS")
             .toExpression());
   }
   arguments.add(Models.toLiteral(f, conf.getTrueFormat()));
   arguments.add(Models.toLiteral(f, conf.getFalseFormat()));
   arguments.add(Models.toLiteral(f, conf.getDateFormat()));
   arguments.add(Models.toLiteral(f, conf.getDateTimeFormat()));
   statements.add(
       new TypeBuilder(f, context.resolve(CsvConfiguration.class))
           .newObject(arguments)
           .toReturnStatement());
   return f.newMethodDeclaration(
       new JavadocBuilder(f)
           .text("Returns this CSV format configuration.")
           .returns()
           .text("CSV format configuration")
           .toJavadoc(),
       new AttributeBuilder(f).Protected().toAttributes(),
       context.resolve(CsvConfiguration.class),
       f.newSimpleName(METHOD_CONFIG),
       Collections.<FormalParameterDeclaration>emptyList(),
       statements);
 }
 private SupportGenerator(
     EmitContext context, ModelDeclaration model, Configuration configuration) {
   assert context != null;
   assert model != null;
   assert configuration != null;
   this.context = context;
   this.model = model;
   this.conf = configuration;
   this.f = context.getModelFactory();
 }
 private MethodDeclaration createSystemIdMethod(
     EmitContext context, ModelDeclaration model, PropertySymbol sid) {
   assert context != null;
   assert model != null;
   assert sid != null;
   ModelFactory f = context.getModelFactory();
   List<Statement> statements = Lists.create();
   statements.add(
       new ExpressionBuilder(f, f.newThis())
           .method(context.getValueGetterName(sid.findDeclaration()))
           .toReturnStatement());
   return f.newMethodDeclaration(
       null,
       new AttributeBuilder(f).annotation(context.resolve(Override.class)).Public().toAttributes(),
       context.resolve(long.class),
       f.newSimpleName("__tgc__SystemId"),
       Collections.<FormalParameterDeclaration>emptyList(),
       statements);
 }
 private void emit() throws IOException {
   ClassDeclaration decl =
       f.newClassDeclaration(
           new JavadocBuilder(f)
               .text("Supports CSV for ")
               .linkType(context.resolve(model.getSymbol()))
               .text(".")
               .toJavadoc(),
           new AttributeBuilder(f).Public().toAttributes(),
           context.getTypeName(),
           Collections.<TypeParameterDeclaration>emptyList(),
           null,
           Collections.singletonList(
               f.newParameterizedType(
                   context.resolve(DataModelStreamSupport.class),
                   context.resolve(model.getSymbol()))),
           createMembers());
   context.emit(decl);
 }
 private MethodDeclaration createGetSupportedType() {
   MethodDeclaration decl =
       f.newMethodDeclaration(
           null,
           new AttributeBuilder(f)
               .annotation(context.resolve(Override.class))
               .Public()
               .toAttributes(),
           f.newParameterizedType(
               context.resolve(Class.class), context.resolve(model.getSymbol())),
           f.newSimpleName("getSupportedType"),
           Collections.<FormalParameterDeclaration>emptyList(),
           Arrays.asList(
               new Statement[] {
                 new TypeBuilder(f, context.resolve(model.getSymbol()))
                     .dotClass()
                     .toReturnStatement()
               }));
   return decl;
 }
 private Statement createReaderStatement(PropertyDeclaration property) {
   assert property != null;
   SimpleName optionGetterName = context.getOptionGetterName(property);
   Expression option =
       new ExpressionBuilder(f, createModelParameterName())
           .method(optionGetterName)
           .toExpression();
   Statement fill =
       new ExpressionBuilder(f, createParserFieldName()).method("fill", option).toStatement();
   return fill;
 }
 private Statement createNullCheck(SimpleName parameter) {
   assert parameter != null;
   return f.newIfStatement(
       new ExpressionBuilder(f, parameter)
           .apply(InfixOperator.EQUALS, Models.toNullLiteral(f))
           .toExpression(),
       f.newBlock(
           new TypeBuilder(f, context.resolve(IllegalArgumentException.class))
               .newObject(
                   Models.toLiteral(
                       f, MessageFormat.format("{0} must not be null", parameter.getToken())))
               .toThrowStatement()));
 }
 private MethodDeclaration createDeletedMethod(
     EmitContext context, ModelDeclaration model, PropertySymbol deleteFlagOrNull) {
   assert context != null;
   assert model != null;
   ModelFactory f = context.getModelFactory();
   List<Statement> statements = Lists.create();
   if (deleteFlagOrNull == null) {
     statements.add(new ExpressionBuilder(f, Models.toLiteral(f, false)).toReturnStatement());
   } else {
     statements.add(
         new ExpressionBuilder(f, f.newThis())
             .method(context.getOptionGetterName(deleteFlagOrNull.findDeclaration()))
             .method("has", f.newSimpleName(FIELD_DELETE_FLAG_VALUE))
             .toReturnStatement());
   }
   return f.newMethodDeclaration(
       null,
       new AttributeBuilder(f).annotation(context.resolve(Override.class)).Public().toAttributes(),
       context.resolve(boolean.class),
       f.newSimpleName("__tgc__Deleted"),
       Collections.<FormalParameterDeclaration>emptyList(),
       statements);
 }
    private MethodDeclaration createCreateWriter() {
      SimpleName path = f.newSimpleName("path");
      SimpleName stream = f.newSimpleName("stream");
      List<Statement> statements = Lists.create();
      statements.add(createNullCheck(path));
      statements.add(createNullCheck(stream));

      SimpleName emitter = f.newSimpleName("emitter");
      statements.add(
          new TypeBuilder(f, context.resolve(CsvEmitter.class))
              .newObject(
                  stream,
                  path,
                  new ExpressionBuilder(f, f.newThis()).method(METHOD_CONFIG).toExpression())
              .toLocalVariableDeclaration(context.resolve(CsvEmitter.class), emitter));

      statements.add(
          new TypeBuilder(f, f.newNamedType(f.newSimpleName(NAME_WRITER)))
              .newObject(emitter)
              .toReturnStatement());

      MethodDeclaration decl =
          f.newMethodDeclaration(
              null,
              new AttributeBuilder(f)
                  .annotation(context.resolve(Override.class))
                  .Public()
                  .toAttributes(),
              Collections.<TypeParameterDeclaration>emptyList(),
              context.resolve(
                  f.newParameterizedType(
                      context.resolve(DataModelWriter.class), context.resolve(model.getSymbol()))),
              f.newSimpleName("createWriter"),
              Arrays.asList(
                  f.newFormalParameterDeclaration(context.resolve(String.class), path),
                  f.newFormalParameterDeclaration(context.resolve(OutputStream.class), stream)),
              0,
              Arrays.asList(context.resolve(IOException.class)),
              f.newBlock(statements));
      return decl;
    }
 private MethodDeclaration createGetter(
     com.asakusafw.utils.java.model.syntax.Type type, String name, Expression value) {
   assert type != null;
   assert name != null;
   assert value != null;
   return f.newMethodDeclaration(
       null,
       new AttributeBuilder(f)
           .annotation(context.resolve(Override.class))
           .Public()
           .toAttributes(),
       type,
       f.newSimpleName(name),
       Collections.<FormalParameterDeclaration>emptyList(),
       Arrays.asList(new ExpressionBuilder(f, value).toReturnStatement()));
 }
 private List<Statement> createConstructorBody() {
   List<Statement> results = new ArrayList<Statement>();
   results.add(
       f.newIfStatement(
           new ExpressionBuilder(f, createParserFieldName())
               .apply(InfixOperator.EQUALS, Models.toNullLiteral(f))
               .toExpression(),
           f.newBlock(
               new TypeBuilder(f, context.resolve(IllegalArgumentException.class))
                   .newObject(Models.toLiteral(f, createParserFieldName().getToken()))
                   .toThrowStatement())));
   results.add(
       new ExpressionBuilder(f, f.newThis(null))
           .field(createParserFieldName())
           .assignFrom(createParserFieldName())
           .toStatement());
   return results;
 }
 private long computeModelVersion(
     EmitContext context, ModelDeclaration model, CacheSupportTrait trait) {
   assert context != null;
   assert model != null;
   assert trait != null;
   long hash = 1;
   final long prime = 31;
   hash = hash * prime + context.getQualifiedTypeName().toNameString().hashCode();
   hash = hash * prime + trait.getSid().getName().identifier.hashCode();
   hash = hash * prime + trait.getTimestamp().getName().identifier.hashCode();
   for (PropertyDeclaration property : model.getDeclaredProperties()) {
     hash = hash * prime + property.getName().identifier.hashCode();
     com.asakusafw.dmdl.semantics.Type type = property.getType();
     assert type instanceof BasicType;
     hash = hash * prime + ((BasicType) type).getKind().name().hashCode();
   }
   return hash;
 }
 private Name generateSupport(EmitContext context, ModelDeclaration model) throws IOException {
   assert context != null;
   assert model != null;
   EmitContext next =
       new EmitContext(
           context.getSemantics(),
           context.getConfiguration(),
           model,
           CATEGORY_STREAM,
           "{0}CsvSupport");
   LOG.debug("Generating CSV support for {}", context.getQualifiedTypeName().toNameString());
   SupportGenerator.emit(next, model, model.getTrait(CsvSupportTrait.class).getConfiguration());
   LOG.debug(
       "Generated CSV support for {}: {}",
       context.getQualifiedTypeName().toNameString(),
       next.getQualifiedTypeName().toNameString());
   return next.getQualifiedTypeName();
 }
 private Name generateExporter(EmitContext context, ModelDeclaration model, Name supportName)
     throws IOException {
   assert context != null;
   assert model != null;
   assert supportName != null;
   EmitContext next =
       new EmitContext(
           context.getSemantics(),
           context.getConfiguration(),
           model,
           CATEGORY_STREAM,
           "Abstract{0}CsvExporterDescription");
   LOG.debug(
       "Generating CSV exporter description for {}",
       context.getQualifiedTypeName().toNameString());
   DescriptionGenerator.emitExporter(next, model, supportName);
   LOG.debug(
       "Generated CSV exporter description for {}: {}",
       context.getQualifiedTypeName().toNameString(),
       next.getQualifiedTypeName().toNameString());
   return next.getQualifiedTypeName();
 }